SSRS 堆叠柱状图如何按各月数量排序并保持图例和颜色一致?
结论
你的判断基本正确:SeriesFrequency 按月份计算,会随月份变化,因此不能作为指控类型的固定身份。
SSRS 常规堆叠图的系列顺序作用于整张图。以 RCSPrimary 作为系列组时,仅修改系列组的排序表达式,无法让同一组系列在每个月采用不同的堆叠顺序。
如果需要在每个月内部按数量排序,可以用排名作为系列组,再根据实际的 RCSPrimary 为每个数据点指定颜色,并单独制作图例。这需要调整图表结构。
为什么排名分组会导致图例和颜色变化?
假设有以下月度汇总数据:
| Month_ID | RCSPrimary | 数量 | SeriesFrequency |
|---|---|---|---|
| 202503 | 类型A | 12 | 1 |
| 202503 | 类型B | 5 | 2 |
| 202504 | 类型A | 3 | 2 |
| 202504 | 类型B | 9 | 1 |
按 SeriesFrequency 分组后,系列 1 在 202503 表示类型A,在 202504 则表示类型B。自动调色板通常按系列分配颜色,因此同一类型在不同月份可能显示为不同颜色。
如果系列组同时包含 RCSPrimary 和 SeriesFrequency,同一类型可能因为排名不同而被拆成多个系列。图例文字不会改变系列的分组身份,即使都显示 RCSPrimary,也可能出现多个同名图例项。
方案一:按类型分组,保留统一的堆叠顺序
如果报表更重视跨月份比较同一种指控,建议使用以下配置:
- Category group:Month_ID。
- Series group:RCSPrimary。
- Values:每月、每种类型的指控数量。
- 系列排序:固定的业务顺序,或各类型跨月份的总数量。
这种结构可以保持系列含义和图例一致,但各月的堆叠顺序也会一致,无法随当月数量重新排列。
方案二:按月度排名分组,使用固定颜色和独立图例
如果必须在每个月内部按数量排序,可以采用以下做法。
1. 先汇总数量,再计算月内排名
下面的 SQL 以 YourSource 为示例数据源名称,需要替换为实际表、视图或原查询。假设其中包含 Month_ID、RCSPrimary 和 Allegation 三个字段:
WITH MonthlyCounts AS (
SELECT
Month_ID,
RCSPrimary,
COUNT(Allegation) AS AllegationCount
FROM YourSource
GROUP BY
Month_ID,
RCSPrimary
), RankedCounts AS (
SELECT
Month_ID,
RCSPrimary,
AllegationCount,
ROW_NUMBER() OVER (
PARTITION BY Month_ID
ORDER BY AllegationCount DESC, RCSPrimary ASC
) AS SeriesFrequency
FROM MonthlyCounts
)
SELECT
Month_ID,
RCSPrimary,
AllegationCount,
SeriesFrequency
FROM RankedCounts
ORDER BY
Month_ID,
SeriesFrequency;
RCSPrimary 作为第二排序条件,可以让数量相同时的排名保持确定。
COUNT(Allegation) 不统计 Allegation 为 NULL 的记录。如果业务定义是每行都代表一条有效指控,应根据实际数据改用 COUNT(*)。确认统计口径后再决定是否替换。
使用 ROW_NUMBER() 可以保证每个月的每个排名只对应一种类型。RANK() 或 DENSE_RANK() 可能让并列类型获得相同排名,按排名分组后,这些类型可能被合并。
2. 使用排名作为图表系列
配置为:
- Category group:
=Fields!Month_ID.Value。 - Series group:
=Fields!SeriesFrequency.Value。 - Series group 排序:SeriesFrequency 升序。
- Values:
=Sum(Fields!AllegationCount.Value)。
此时,每个系列表示“当月第几名”,每个数据点仍保留实际的 RCSPrimary。
系列排序控制堆叠次序。最大分段最终显示在底部还是顶部,还需要结合图表方向和轴设置检查。
3. 在数据点上按实际类型指定颜色
将颜色表达式设置在堆叠分段对应的数据点 Fill/Color 属性上,读取当前月份与排名交叉位置的 RCSPrimary。
例如,假设实际类型值为“类型A”“类型B”“类型C”:
=Switch(
First(Fields!RCSPrimary.Value) = "类型A", "#4472C4",
First(Fields!RCSPrimary.Value) = "类型B", "#ED7D31",
First(Fields!RCSPrimary.Value) = "类型C", "#70AD47",
True, "#A5A5A5"
)
类型名称和颜色只是示例,需要替换为实际映射。类型较多时,可以在数据集中提供固定的颜色字段,再由数据点表达式读取。
这里的前提是当前数据点仅对应一个 RCSPrimary。应确认表达式作用于数据点,并且没有将 First 的作用域显式设为整个数据集或跨月份的排名系列,否则取到的类型可能不属于当前月份。
4. 隐藏自动图例,单独展示类型图例
排名系列没有固定的类型含义,自动图例无法准确代表这些分段。可以隐藏图表自带图例,在旁边放置一个 Tablix:
- 每个 RCSPrimary 显示一行。
- 用一个单元格显示色块,另一个单元格显示类型名称。
- 色块使用与图表完全相同的类型到颜色映射。
- 按 RCSPrimary 分组,避免同一类型重复显示。
堆叠顺序由月度排名决定,颜色和图例由实际类型决定。
配置时还需要核对什么?
SQL 结果的 ORDER BY 不能替代图表系列组的排序设置,两个位置都应按各自用途配置。
不同月份的类型数量可能不同,缺少的排名应保持为空。不要为了补齐排名而随意填入其他类型,否则颜色和提示信息可能失真。数据点提示建议同时显示月份、RCSPrimary 和数量,方便核查。
另外,如果首尾月份都包含在内,202503 至 202604 实际覆盖 14 个月。需要确认报表要求究竟是这个日期范围,还是包含结束月份在内的 13 个月窗口。
备注:内容仅供参考。
