簡體   English   中英

如何在 Palantir Foundry Workshop 中創建分段累積和圖?

[英]How do I create a segmented cumulative sum graph in Palantir Foundry Workshop?

我有一些代表維護工作的對象,如下所示:

由於上 地位
2021-12-01 打開
2022-06-17 打開
2022-07-05 關閉
2022-07-05 關閉
2022-08-01 打開
2023-09-02 打開

如何在 Palantir Foundry Workshop 中生成分段累積圖,繪制這樣的值?

分段累積圖

您可以使用 Foundry Function 來執行此操作。 創建一個 TypeScript 函數存儲庫並使用以下代碼(有關說明,請參閱內聯注釋):

import { Function, Double, ThreeDimensionalAggregation, IRange, IRangeable, Timestamp, BucketKey, BucketValue } from "@foundry/functions-api";

// Replace MaintenanceJob with your object
// To make your object available, add it in the Settings > Ontology tab
import { ObjectSet, MaintenanceJob } from "@foundry/ontology-api";

export class MyFunctions {
    // You will find this function in Workshop after it's published
    // Replace MaintenanceJob with your object
    @Function()
    public async cumulativeJobsByMonthByStatus(jobs: ObjectSet<MaintenanceJob>): Promise<ThreeDimensionalAggregation<IRange<Timestamp>, string, Double>> {
        const bucketedJobs = await jobs
            .groupBy(j => j.dueOn.byMonth())
            .segmentBy(j => j.status.topValues())
            .count();

        const sortedBucketedJobs = sortBuckets(bucketedJobs);
        const cumulativeSortedBucketedJobs = cumulativeSum3D(sortedBucketedJobs);

        return cumulativeSortedBucketedJobs
    }
}

/**
 * Sort buckets of a 2D or 3D aggregation by the first axis in ascending order
 * 
 * Example input 1:
 * { buckets: [
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: 456 },
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: 123 },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: 789 },
 * ]}
 * 
 * Example output 1:
 * { buckets: [
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: 123 },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: 456 },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: 789 },
 * ]}
 * 
 * Example input 2:
 * { buckets: [
 *   { key: 22, value: 456 },
 *   { key: 21, value: 123 },
 *   { key: 23, value: 789 },
 * ]}
 * 
 * Example output 2:
 * { buckets: [
 *   { key: 21, value: 123 },
 *   { key: 22, value: 456 },
 *   { key: 23, value: 789 },
 * ]}
 * 
 * Example input 3:
 * { buckets: [
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 789 }, { key: "closed", value: 910 }] },
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 123 }, { key: "closed", value: 456 }] },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 314 }, { key: "closed", value: 42 }] },
 * ]}
 * 
 * Example output 3:
 * { buckets: [
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 123 }, { key: "closed", value: 456 }] },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 789 }, { key: "closed", value: 910 }] },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 314 }, { key: "closed", value: 42 }] },
 * ]}
 */
function sortBuckets<K1 extends BucketKey, K2 extends BucketKey, V extends BucketValue>(buckets: ThreeDimensionalAggregation<K1, K2, V>): ThreeDimensionalAggregation<K1, K2, V>;
function sortBuckets<K extends BucketKey, V extends BucketValue>(buckets: TwoDimensionalAggregation<K, V>): TwoDimensionalAggregation<K, V>;
function sortBuckets<K extends BucketKey, V>(buckets: { buckets: { key: K, value: V}[] }): { buckets: { key: K, value: V}[] } {
    return {
        // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
        buckets: buckets.buckets.sort(({ key: k1 }, { key: k2 }) => {
            if (typeof k1 !== typeof k2) throw new Error("Inconsistent bucket key types")

            // If not objects, these must be either numbers or booleans which can be compared like this
            if (typeof k1 !== "object" || typeof k2 !== "object") return Number(k1) - Number(k2);

            // If a bucket doesn't have a minimum, it suggests that it is the global unbounded minimum bucket, so must be lower
            if (!(k1 as IRange<IRangeable>).min) return -1;
            if (!(k2 as IRange<IRangeable>).min) return 1;

            // Otherwise, compare both buckets' minimums
            return (k1 as IRange<IRangeable>).min!.valueOf() - (k2 as IRange<IRangeable>).min!.valueOf();
        }),
    };
}

/**
 * Calculates a cumulative sum for a ThreeDimensionalAggregation over numbers, along the first axis and segmented by the second axis
 * The order of the buckets into the function matters for how the values are aggregated
 * 
 * Example input 1:
 * { buckets: [
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 123 }, { key: "closed", value: 456 }] },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 789 }, { key: "closed", value: 910 }] },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 314 }, { key: "closed", value: 42 }] },
 * ]}
 * 
 * Example output 1:
 * { buckets: [
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 123 }, { key: "closed", value: 456 }] },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 912 }, { key: "closed", value: 1366 }] },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 1226 }, { key: "closed", value: 1408 }] },
 * ]}
 * 
 * Example input 2:
 * { buckets: [
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 314 }, { key: "closed", value: 42 }] },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 789 }, { key: "closed", value: 910 }] },
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 123 }, { key: "closed", value: 456 }] },
 * ]}
 * 
 * Example output 2:
 * { buckets: [
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: [{ key: "open", value: 314 }, { key: "closed", value: 42 }] },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: [{ key: "open", value: 1103 }, { key: "closed", value: 952 }] },
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: [{ key: "open", value: 1226 }, { key: "closed", value: 1408 }] },
 * ]}
 */
const cumulativeSum3D = <T extends BucketKey, U extends BucketKey>(buckets: ThreeDimensionalAggregation<T, U, number>): ThreeDimensionalAggregation<T, U, number> => {
    // This holds the running total for each secondary axis value
    // e.g. you `{ open: 123, closed: 456 }` at some point in the examples above
    const cumulativeBuckets = new Map<U, number>();
    
    return {
        buckets: buckets.buckets.map(b => ({
            key: b.key,
            value: b.value.map(v => {
                // Update the running total with the value we are seeing
                cumulativeBuckets.set(v.key, (cumulativeBuckets.get(v.key) ?? 0) + v.value)

                return {
                    key: v.key,
                    // Use the running total value
                    value: cumulativeBuckets.get(v.key)!,
                }
            })
        }))
    }
}

提交您的更改並發布函數版本。 Palantir Foundry 文檔中有關於如何創建存儲庫和發布函數的分步指南。

在您的創意工坊中,您可以創建一個“圖表:XY”小部件。 作為數據源,選擇您創建的函數並傳入相關的對象集。 還有關於在 Workshop 中使用派生聚合的 Palantir Foundry 文檔

您也可以通過在 Quiver 分析中創建圖表,然后使用Quiver Dashboard來控制布局並將其嵌入到您的 Workshop 應用程序中,從而無需代碼即可執行此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM