// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System.Drawing; using System.Linq; using System.Windows.Forms; using Deltares.Dam.Data; using Deltares.Standard; using Deltares.Standard.EventPublisher; using DevExpress.Utils; using DevExpress.XtraCharts; using Series = DevExpress.XtraCharts.Series; namespace Deltares.Dam.Forms { public partial class LocationScenarioChart : UserControl { // this should really be handled by the location manager... private const string YAxisText = "Safety Factor"; private const string XAxisText = "Soil Profiles"; private DamProjectData damProjectData = null; private readonly LocationJobSymbol locationJobSymbol; private LocationJob locationJob = null; private RWScenarioProfileResult selectedResult = null; private readonly Font defaultTitleFont = new Font("Tahoma", 12F, FontStyle.Bold); private readonly Font defaultAxisFont = new Font("Tahoma", 10F, FontStyle.Regular); public LocationScenarioChart(LocationJobSymbol locationJobSymbol) { InitializeComponent(); chartControl1.ObjectSelected += chartControl1_ObjectSelected; this.locationJobSymbol = locationJobSymbol; DataEventPublisher.OnSelectionChanged += DataEventPublisher_OnSelectionChanged; DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange; DataEventPublisher.OnLoaded += DataEventPublisher_OnLoaded; } private void DataEventPublisher_OnLoaded(object sender, PublishEventArgs e) { var damProject = sender as DamProject; if (damProject != null) { damProjectData = damProject.DamProjectData; } var projectData = sender as DamProjectData; if (projectData != null) { damProjectData = projectData; } } private void chartControl1_ObjectSelected(object sender, HotTrackEventArgs e) { if (e.HitInfo.SeriesPoint != null) { DataEventPublisher.SelectionChanged(e.HitInfo.SeriesPoint.Tag); } } private void DataEventPublisher_OnSelectionChanged(object sender, PublishEventArgs e) { if (sender is LocationJob) { locationJob = sender as LocationJob; UpdateChart(); } else if (sender is RWScenarioProfileResult) { selectedResult = (RWScenarioProfileResult) sender; if (locationJob == null || selectedResult.Location != locationJob.Location) { locationJob = damProjectData.GetLocationJob(selectedResult.Location); UpdateChart(); } else { UpdateSelection(); } } } private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e) { if (sender == locationJob) { UpdateChart(); } else if (sender is LocationJobSymbol) { UpdateChart(); } } private void UpdateChart() { UpdateChartSeries(); UpdateChartAxesLabels(); UpdateChartTitles(); UpdateSelection(); } private void UpdateChartSeries() { // clear existing series chartControl1.Series.Clear(); // get scenario result. If not existing, return. if (locationJob == null || !locationJob.HasRWScenarioResults) return; var scenarioResult = locationJob.LocationResult.RWScenariosResult.GetScenarioResult( locationJobSymbol.CurrentScenarioType); if (scenarioResult == null) return; // build chartseries with the result var results = scenarioResult.RWScenarioProfileResults; var seriesList = results .Select(BuildChartSeries) .Where(chartSeries => chartSeries != null) .ToArray(); // add the chart series to the chart chartControl1.Series.AddRange(seriesList); } private SeriesPoint BuildSeriesPoint(RWScenarioProfileResult result) { var value = result.CalculationResult == CalculationResult.Succeeded ? result.SafetyFactor : 0d; var name = result.SoilGeometryProbability.SoilProfile.Name + " (" + result.SoilGeometryProbability.Probability.ToString() + " %)"; var chartPoint = new SeriesPoint(name, new object[] { value }) { Tag = result }; return chartPoint; } private Series BuildChartSeries(RWScenarioProfileResult result) { if (result.SoilGeometryProbability == null) { return null; } // create series var chartSeries = new Series { ArgumentScaleType = ScaleType.Qualitative, Tag = result, LabelsVisibility = DefaultBoolean.False, ShowInLegend = true }; chartSeries.ChangeView(ViewType.Bar); // add point chartSeries.Points.Add(BuildSeriesPoint(result)); // setup view var barView = (BarSeriesView)chartSeries.View; barView.Color = JobResultInterpreter.GetJobResultColor(result.SafetyFactor, locationJob.DetrimentFactor, true); barView.FillStyle.FillMode = FillMode.Solid; barView.Border.Thickness = 2; barView.BarWidth = 0.1; // done return chartSeries; } private void UpdateChartAxesLabels() { // checked cast var diagram = chartControl1.Diagram as XYDiagram; if (diagram == null) return; // axes labels diagram.AxisY.Title.Text = YAxisText; diagram.AxisY.Title.Visible = true; diagram.AxisY.Title.Font = defaultAxisFont; diagram.AxisX.Title.Text = XAxisText; diagram.AxisX.Title.Visible = true; diagram.AxisX.Title.Font = defaultAxisFont; diagram.AxisX.Label.Staggered = true; } private void UpdateChartTitles() { chartControl1.Titles.Clear(); var titles = BuildChartTitle(); if (titles.Length > 0) { chartControl1.Titles.AddRange(titles); } } private ChartTitle[] BuildChartTitle() { if ( locationJob == null ) { return new ChartTitle[0]; } RWScenarioResult scenarioResult = null; if (locationJob.LocationResult.RWScenariosResult != null) { scenarioResult = locationJob.LocationResult.RWScenariosResult.GetScenarioResult( locationJobSymbol.CurrentScenarioType); } var scenarioType = string.Format("No results for {0}", locationJobSymbol.CurrentScenarioType); if (scenarioResult != null) { scenarioType = locationJobSymbol.CurrentScenarioType.ToString(); } var subTitleText = string.Format("Location \"{0}\", {1}", locationJob.Location.Name, scenarioType); return new [] { new ChartTitle { Text = subTitleText, Font = defaultTitleFont} }; } private void UpdateSelection() { foreach (Series series in chartControl1.Series) { var view = (BarSeriesView)series.View; var selectedTag = series.Tag != null && series.Tag == selectedResult; view.Border.Color = selectedTag ? Color.Black : series.View.Color; } } } }