public GetAssetLimitChartByDayOutput GetAssetLimitChartByDay(GetAssetLimitChartByDayInput input) { Asset asset = _assetManager.GetAsset(input.AssetId, input.AssetName); GetAssetLimitChartByDayOutput output = new GetAssetLimitChartByDayOutput { AssetId = (asset != null) ? asset.Id : 0, AssetName = (asset != null) ? asset.Name : "", AssetDescription = (asset != null) ? asset.Description : "", StartTimestamp = _iowManager.NormalizeStartDay(input.StartTimestamp), NumberLimits = 0, CanvasJS = new CanvasJSBar { exportEnabled = true, title = new CanvasJSBarTitle { text = "" /*(asset != null) ? (asset.Name + ": " + asset.Description) : ""*/ }, axisX = new CanvasJSBarAxisX { }, axisY = new CanvasJSBarAxisY { title = "Deviation hours" }, data = new List<CanvasJSBarData>() } }; output.EndTimestamp = _iowManager.NormalizeEndDay(output.StartTimestamp, input.EndTimestamp); List<AssetLimitStatsByDay> assetLimits = _assetHealthManager.GetAssetLimitStatsByDay(input.AssetId, input.AssetName, input.StartTimestamp, input.EndTimestamp, true, false); if (assetLimits != null && assetLimits.Count > 0 && assetLimits[0].Limits != null && assetLimits[0].Limits.Count > 0 ) { // There should be exactly one asset // Each limit will be its own series output.NumberLimits = assetLimits[0].Limits.Count; foreach (LimitStatsByDay limit in assetLimits[0].Limits) { CanvasJSBarData data = new CanvasJSBarData { name = limit.Criticality.ToString() + " - " + limit.LevelName, type = "stackedColumn", legendText = limit.Criticality.ToString() + " - " + limit.LevelName, showInLegend = true, color = ChartColors.CriticalForeground(limit.Criticality), dataPoints = new List<CanvasJSBarDataPoints>() }; // Now add the daily records if (limit.Days != null) { foreach (LimitStatDays day in limit.Days) { CanvasJSBarDataPoints point = new CanvasJSBarDataPoints { y = day.DurationHours, label = day.Day.ToString("m") }; data.dataPoints.Add(point); } } output.CanvasJS.data.Add(data); } } return output; }
public GetAssetLevelChartOutput GetAssetLevelChartCanvasJS(GetAssetLevelChartInput input) { var localize = _localizationManager.GetSource("AssetManager"); // Start the chart GetAssetLevelChartOutput output = new GetAssetLevelChartOutput { CanvasJS = new CanvasJSBar { exportEnabled = true, title = new CanvasJSBarTitle { }, axisX = new CanvasJSBarAxisX { interval=1 }, axisY = new CanvasJSBarAxisY { }, data = new List<CanvasJSBarData>() } }; // Get the list of assets List<Asset> assets = _assetManager.GetAssetList().OrderBy(p => p.Name).ToList(); if (assets == null || assets.Count <= 0) return output; // Get the asset/level/time combinations. Not all assets will appear. // Specify an aggregation of 0, which means one time record per asset/level. // Sort by criticality and level first, to simplify matching later. AssetDeviationSummaryOutput assetSummary = _assetHealthManager.GetAssetLevelTimeSummary(input.StartTimestamp, 0); if (assetSummary == null || assetSummary.AssetDeviations == null) return output; output.StartTimestamp = assetSummary.StartTimestamp; output.EndTimestamp = assetSummary.EndTimestamp; output.NumberPeriods = assetSummary.NumberPeriods; output.HoursInPeriod = assetSummary.HoursInPeriod; List<AssetDeviationSummary> assetDeviations = assetSummary.AssetDeviations .OrderBy(p => p.Criticality).ThenBy(p => p.LevelName).ThenBy(p => p.AssetName) .ToList(); // i is the index into the current record in assetDeviations int i = 0; // Get the set of distinct level names var query = (from x in assetDeviations select new { x.Criticality, x.LevelName }) .Distinct().OrderBy(x => x.Criticality).ThenBy(x => x.LevelName); var allLevels = query.ToList(); if (allLevels == null || allLevels.Count <= 0) return output; // Build the chart //output.CanvasJS.title.text = "Asset health by level over time"; output.CanvasJS.axisY.title = "Deviation hours from " + assetSummary.StartTimestamp.ToString("d") + " to now"; // Each distinct level will be its own bar in the stack foreach (var level in allLevels) { CanvasJSBarData data = new CanvasJSBarData { name = level.Criticality.ToString() + " - " + level.LevelName, type = "stackedBar", legendText = level.Criticality.ToString() + " - " + level.LevelName, showInLegend = true, color = ChartColors.CriticalForeground(level.Criticality), dataPoints = new List<CanvasJSBarDataPoints>() }; // Now add the assets to the level structure foreach(Asset asset in assets) { CanvasJSBarDataPoints points = new CanvasJSBarDataPoints { y = 0, label = asset.Name }; // assetDeviations is sorted by criticality, then level name, then asset name // Go forward in assetDeviations until the end or a match on the first criteria (criticality) for (; i < assetDeviations.Count && assetDeviations[i].Criticality < level.Criticality; i++); // Go forward in assetDeviations until the end or a match on the first and second criteria for (; i < assetDeviations.Count && assetDeviations[i].Criticality <= level.Criticality && string.Compare(assetDeviations[i].LevelName, level.LevelName) < 0; i++) ; // Go forward in assetDeviations until the end or a match on all three criteria for (; i < assetDeviations.Count && assetDeviations[i].Criticality <= level.Criticality && string.Compare(assetDeviations[i].LevelName, level.LevelName) <= 0 && string.Compare(assetDeviations[i].AssetName, asset.Name) < 0; i++) ; // If a match, then use the duration hours as the Y value // Note that assetDeviations was generated for a single time period, so there should only be one DeviationDetails record. if (i < assetDeviations.Count && assetDeviations[i].Criticality == level.Criticality && string.Compare(assetDeviations[i].LevelName, level.LevelName) == 0 && string.Compare(assetDeviations[i].AssetName, asset.Name) == 0) { points.y += assetDeviations[i].DeviationDetails[0].DurationHours; } data.dataPoints.Add(points); } output.CanvasJS.data.Add(data); } return output; }