({ title, chartSpec }, ctx)
| 74 | const seriesNames = chart.series.map(({ name }) => name); |
| 75 | if (new Set(seriesNames).size !== seriesNames.length) { |
| 76 | ctx.addIssue({ |
| 77 | code: z.ZodIssueCode.custom, |
| 78 | path: ["chart", "series"], |
| 79 | message: "Series names must be unique.", |
| 80 | }); |
| 81 | } |
| 82 | |
| 83 | for (const [index, series] of chart.series.entries()) { |
| 84 | const labels = series.data.map(({ label }) => label); |
| 85 | const labelsMatchCategories = |
| 86 | labels.length === categories.length && |
| 87 | new Set(labels).size === labels.length && |
| 88 | labels.every((label) => categories.includes(label)); |
| 89 | if (!labelsMatchCategories) { |
| 90 | ctx.addIssue({ |
| 91 | code: z.ZodIssueCode.custom, |
| 92 | path: ["chart", "series", index, "data"], |
| 93 | message: |
| 94 | "Each series must contain exactly one data point for every axis category.", |
| 95 | }); |
| 96 | } |
| 97 | } |
| 98 | }); |
| 99 | |
| 100 | export const RenderChart = defineChannelComponent({ |
| 101 | name: "render_chart", |
| 102 | description: |
| 103 | "Render a native Slack data visualization in the conversation. Use this " + |
| 104 | "after analyzing data such as an uploaded CSV. Supports pie, bar, area, " + |
| 105 | "and line charts. Series data labels must exactly match the ordered axis " + |
| 106 | "categories.", |
| 107 | parameters: schema, |
| 108 | render({ title, chart }, { platform }) { |
| 109 | if (platform !== "slack") { |
| 110 | return ( |
| 111 | <Section> |
| 112 | Native data visualizations are currently only available in Slack. |
| 113 | </Section> |
| 114 | ); |
| 115 | } |
nothing calls this directly
no test coverage detected