简体   繁体   English

如何在SSRS上设计条形图

[英]How to design bar chart on SSRS

I want to create reports like below picture's report on SSRS. 我想创建如下图所示的SSRS报告。

Yellow parts mean SET_PHASE , Green parts mean PROD_PHASE 黄色部分表示SET_PHASE ,绿色部分表示PROD_PHASE

预期

And my query result like this: 和我的查询结果是这样的:

询问

I want to show for per line, all order and I want to show for per order, SETUP and PRODUCTION depends on duratıon time. 我想为每条订单显示所有订单,我想为每订单显示SETUP和PRODUCTION取决于持续时间。

SET_PHASE 's duration time is SET_DURATION , SET_PHASE的持续时间为SET_DURATION

PROD_PHASE 's duration time is PROD_DURATION PROD_PHASE的持续时间为PROD_DURATION

I hope so my query is clear :) Could you help me about issue? 我希望我的查询很清楚:)您能帮我解决问题吗?


Answer: 回答:

Hello Alan, 你好艾伦,

Current situation I have just these data: 目前的情况我只有这些数据:

PROD100059335   SETUP   PRODUCTION  1   14  LINE 4
PROD100058991   SETUP   PRODUCTION  1   5   LINE 6
PROD100059259   SETUP   PRODUCTION  2   24  LINE 4
PROD100059188   SETUP   PRODUCTION  1   3   LINE 2
PROD100059248   SETUP   PRODUCTION  1   15  LINE 2
PROD100059055   SETUP   PRODUCTION  2   23  LINE 2
PROD100058754   SETUP   PRODUCTION  5   18  LINE 6

And If I use your query I just show "PROD100058754", "PROD100059259", "PROD100059055" these order. 如果我使用您的查询,我只会显示“ PROD100058754”,“ PROD100059259”,“ PROD100059055”这些顺序。 I don't understand why other data lost. 我不明白为什么其他数据会丢失。

until "DECLARE @n TABLE(n int)" part I can show other data. 直到“ DECLARE @n TABLE(n int)”部分我可以显示其他数据。 but after that I can not show. 但之后我无法显示。

And I applied procedure on SSRS my report shows like this: 我在SSRS上应用了程序,我的报告显示如下:

在此处输入图片说明

I couldn't do correctly and I don't know how can I fix them:( 我无法正确执行,也不知道如何解决它们:(

for example "PROD100059259" this order normally has setup phase but on the report I don't have yellow field. 例如“ PROD100059259”,此订单通常具有设置阶段,但在报告中我没有黄色字段。

Do you have any suggestions for me? 您对我有什么建议吗?

OK, here is an attempt to give you what you want but there are a few caveats: 好的,这是尝试为您提供所需的内容,但有一些警告:

  1. The durations are scaled and no operation can take less than 1 time slot so the setup vs production duration is only approximate 持续时间是按比例缩放的,并且任何操作都不能少于1个时隙,因此设置与生产的持续时间仅是近似的
  2. I haven't found a good way of labelling each bar so I've used tooltips 我还没有找到标记每个条的好方法,所以我使用了工具提示

First the code ... I've added lots of comments so hopefully you can follow it thru, it's based on your sample data. 首先是代码 ...我添加了很多注释,因此希望您可以根据您的示例数据继续关注它。

NOTE: I've update the table as it now seems like you are using integer durations rather than the 00:00 format from your first example. 注意:我已经更新了表,因为现在好像您使用的是整数持续时间,而不是第一个示例中的00:00格式。

-- CREATE A TEST TABLE AND POPULATE IT
DECLARE @data TABLE(STR_ORDER_ID varchar(20), SET_DURATION varchar(10), PROD_DURATION varchar(10), Set_decimal int, Prod_Decimal int, Line varchar(10))

INSERT INTO @data
VALUES
('PROD100059335', NULL, NULL, 1, 14, 'LINE 4'),
('PROD100058991', NULL, NULL,1, 5, 'LINE 6'),
('PROD100059259', NULL, NULL,2, 24, 'LINE 4'),
('PROD100059188', NULL, NULL,1, 3, 'LINE 2'),
('PROD100059248', NULL, NULL,1, 15, 'LINE 2'),
('PROD100059055', NULL, NULL,2, 23, 'LINE 2'),
('PROD100058754', NULL, NULL,5, 18, 'LINE 6')

DECLARE @Gap int = 2 -- determines how many columns we use to separate each order

-- ASSUME durations are in hours/minutes or minutes/seconds and convert them to decimal minutes or decimal seconds respectively

-- COMMENTED THIS AS WE NO LONGER NEED IT. No longer required as durations are now integer values.
--UPDATE d 
--    SET 
--        Set_decimal = (CAST(LEFT(d.SET_DURATION, len(d.SET_DURATION)-3) AS INT) * 60) +  CAST(RIGHT(d.SET_DURATION, 2) AS INT)  ,
--        Prod_Decimal = (CAST(LEFT(d.PROD_DURATION, len(d.PROD_DURATION)-3) AS INT) * 60) +  CAST(RIGHT(d.PROD_DURATION, 2) AS INT) 
--FROM @data d


-- CREATE A NORMALISED TABLE, this will just help to make the next steps simpler
DECLARE @normData TABLE(RowId INT IDENTITY (1,1), Line varchar(10), STR_ORDER_ID varchar(20), OperationOrder int, Operation varchar(10), Duration int)
INSERT INTO @normData (Line, STR_ORDER_ID, OperationOrder, Operation, Duration)
SELECT * FROM (
SELECT Line, STR_ORDER_ID, 1 as OperationOrder , 'SET' as Operation , Set_decimal FROM @data 
UNION
SELECT Line, STR_ORDER_ID, 2 , 'PROD' , Prod_decimal FROM @data 
UNION
SELECT Line, STR_ORDER_ID, 3 , 'GAP' , @Gap FROM @data )  u -- this adds dummy data that will act as gaps in hte timeline. Change 5 to whatever value suits you best
    ORDER BY Line, STR_ORDER_ID, OperationOrder

-- find the largest line running total duration per line and scale it to fit to 240 (so we dont go over 256 column limit in SSRS)
DECLARE @MaxDur INT = (SELECT MAX(rt) FROM (
                        select  *
                            , SUM(Duration) OVER(PARTITION BY Line ORDER BY Line, STR_ORDER_ID, OperationOrder) AS Rt
                         from @normData) mRt)


-- Now scale the values back so they fit but don't let any value become less than 1
IF @MaxDur > 240
    BEGIN
        UPDATE nd 
            SET Duration = CASE WHEN nd.Duration / (@MaxDur/240) <1 THEN 1 ELSE nd.Duration / (@MaxDur/240) END
            FROM @normData nd
    END

/* check what we have so far by uncommenting this bit
select  *
    , SUM(Duration) OVER(PARTITION BY Line ORDER BY Line, STR_ORDER_ID, OperationOrder) AS Rt
 from @normData
--*/    

-- ================================================================ --
-- At this point you 'may' have enough data to plot a bar chart. == --
-- ================================================================ --

-- CREATE A SIMPLE NUMBERS TABLE, we'll need this to act as our time series
DECLARE @n TABLE(n int)
DECLARE @i int  = 0
DECLARE @t int  = @MaxDur --(SELECT max(Duration) +5 FROM @normData) -- simple loop counter target set to slightly bigger than our highest duration
WHILE @i<@t
    BEGIN
        INSERT INTO @n SELECT @i
        SET @i = @i +1
    END

-- Join our numbers table to our real data
-- This will give us at least 1 row per time slot and associated activity during that time slot.
-- We can plot this driectly as a matrix.
SELECT * 
    FROM @n n
        LEFT JOIN ( 
                -- Sub queries below give use a runnintg total, we then join this back to itself to get the previous 
                -- running total and this will give us the 'time range' for each operation.
                SELECT 
                    a.*
                    , ISNULL(b.Rt,0)+1 AS TimeStart
                    , a.RT AS TimeEnd
                    FROM
                    (SELECT *
                            , SUM(Duration) OVER(PARTITION BY Line ORDER BY Line, STR_ORDER_ID, OperationOrder) AS Rt
                         from @normData
                    ) a
                LEFT JOIN 
                    (SELECT *
                            , SUM(Duration) OVER(PARTITION BY Line ORDER BY Line, STR_ORDER_ID, OperationOrder) AS Rt
                         from @normData
                    ) b
                    ON a.RowId = b.RowId + 1 and a.Line = b.Line 
                ) d
            ON n.n between d.TimeStart and d.TimeEnd
    ORDER BY Line, STR_ORDER_ID, OperationOrder, n, TimeStart, TimeEnd

You can use the code above in your dataset. 您可以在数据集中使用上面的代码。

The report design: The report is very simple. 报告设计:报告非常简单。 It's a matrix with a single row group based on Line and a single column group based on n which is our time slot number. 它是一个矩阵,其中有一个基于Line的单行组和一个基于n的单列组, n是我们的时隙号。

I've added a blank row to act as a spacer between the 'bars'. 我添加了一个空白行来充当“条”之间的间隔。

在此处输入图片说明

The expression of the cell background is 细胞背景的表达是

=SWITCH(
Fields!OperationOrder.Value = 1, "Yellow",
Fields!OperationOrder.Value = 2, "Green",
Fields!OperationOrder.Value = 3, Nothing,
True, Nothing
)

There is also a tooltip which displays STR_ORDER_ID and the operation name. 还有一个工具提示,显示STR_ORDER_ID和操作名称。

You get the following output. 您将获得以下输出。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM