Map 함수 기반 스타일
함수로 객체의 동적 값을 계산하여 Selection의 속성 목록에 표시하거나 색상 스타일에 사용할 수 있습니다.
함수 계약
일반 Map 스타일 함수는 다음 조건을 충족해야 합니다.
- 인수는 객체 배열 또는 객체 집합 하나입니다.
- 반환 맵의 키는 입력에 있는 객체입니다.
- 맵의 값은 문자열 또는 숫자입니다.
TypeScript v1은 FunctionsMap을, TypeScript v2는 ObjectSpecifier 키의 Record를 반환합니다.
배치와 결과의 일관성
Map은 레이어 전체가 아니라 객체의 일부 배치를 함수에 전달합니다. 함수는 받은 배치의 모든 객체에 값을 반환해야 합니다.
같은 객체의 결과는 같은 배치에 다른 어떤 객체가 들어왔는지에 따라 달라지면 안 됩니다. 배치 전체의 최솟값, 평균이나 크기로 개별 객체 결과를 정하는 방식은 이 조건을 충족하지 못할 수 있습니다.
노선별 취소율 예시
아래 예시는 ExampleDataRoute의 flights 링크로 연결된 항공편 중 cancelled가 true인 비율을 계산합니다. 생성 SDK에 해당 객체 및 링크 바인딩이 있어야 하며 항공편의 cancelled는 Boolean 값으로 정의한 구성을 전제로 합니다.
노선별 취소율은 그 노선의 연결 항공편만 사용하므로 입력 배치의 다른 노선에 영향을 받지 않습니다. 항공편이 없거나 취소 여부가 비어 있으면 취소율을 0으로 대체하지 않고 오류로 알립니다.
TypeScript v1
import { Double, Function, FunctionsMap, UserFacingError } from "@foundry/functions-api";
import { ExampleDataRoute } from "@foundry/ontology-api";
export class DerivedPropertyFunctions {
@Function()
public async flightCancellationPercentage(
routes: ExampleDataRoute[],
): Promise<FunctionsMap<ExampleDataRoute, Double>> {
const result = new FunctionsMap<ExampleDataRoute, Double>();
await Promise.all(routes.map(async route => {
const flights = await route.flights.allAsync();
if (flights.length === 0) {
throw new UserFacingError("항공편이 없는 노선의 취소율은 계산할 수 없습니다.");
}
let cancelledCount = 0;
for (const flight of flights) {
if (flight.cancelled == null) {
throw new UserFacingError("항공편의 취소 여부가 필요합니다.");
}
if (flight.cancelled === true) {
cancelledCount += 1;
}
}
result.set(route, (cancelledCount / flights.length) * 100);
}));
return result;
}
}
TypeScript v2
OSDK 객체의 다중 링크는 $link에서 접근하며 asyncIter로 페이지를 읽습니다.
import type { ObjectSpecifier, Osdk } from "@osdk/client";
import type { Double } from "@osdk/functions";
import type { ExampleDataRoute } from "@ontology/sdk";
export default async function flightCancellationPercentage(
routes: Osdk.Instance<ExampleDataRoute>[],
): Promise<Record<ObjectSpecifier<ExampleDataRoute>, Double>> {
const result: Record<ObjectSpecifier<ExampleDataRoute>, Double> = {};
await Promise.all(routes.map(async route => {
let flightCount = 0;
let cancelledCount = 0;
for await (const flight of route.$link.flights.asyncIter({ $select: ["cancelled"] })) {
if (flight.cancelled == null) {
throw new Error("항공편의 취소 여부가 필요합니다.");
}
flightCount += 1;
if (flight.cancelled === true) {
cancelledCount += 1;
}
}
if (flightCount === 0) {
throw new Error("항공편이 없는 노선의 취소율은 계산할 수 없습니다.");
}
result[route.$objectSpecifier] = (cancelledCount / flightCount) * 100;
}));
return result;
}
두 구현은 독립적인 노선 조회를 병렬로 시작합니다. v2는 모든 항공편을 별도 배열로 모으지 않고 읽으면서 개수를 셉니다. 실제 조회에는 해당 Functions 또는 OSDK 런타임의 데이터 접근과 조회 한도가 적용됩니다.
Workshop Map 위젯의 추가 인수
Workshop의 Map 위젯에서는 기본 객체 입력 외에 추가 함수 인수를 받을 수 있습니다. 첫 인수는 계산 대상 객체들이며 위젯이 자동으로 제공합니다.
위젯 구성에는 추가 인수들만 나타납니다. 각 값을 Workshop 변수로 지정하여 스타일 계산에 전달할 수 있습니다.