Files
2026-04-17 14:55:32 -04:00

453 lines
20 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace DTS.Slice.PedestrianAndHeadReports
{
/// <summary>
/// this is the base class for all pedestrian and head reports
/// it contains all the common items between the reports
/// </summary>
public abstract class ReportBase : INotifyPropertyChanged
{
/// <summary>
/// these functions make us WPF/dependency property friendly, and also
/// adds a convenient way for us to notify consumers when a property has changed
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, String propertyName)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
public void SetField(KnownGraphs graph, string channelId, GraphChannel.Fields field, string value)
{
_graphs[graph.ToString()].GetGraphChannel(channelId).SetValue(field, value);
DrawGraph(graph);
if (graph == KnownGraphs.HEAD_Acceleration)
{
DrawGraph(KnownGraphs.HEAD_ResultantAcceleration,
GetGraph(KnownGraphs.HEAD_ResultantAcceleration.ToString()).Chart);
}
}
public void SetField(KnownGraphs graph, ReportGraph.Fields field, string value)
{
_graphs[graph.ToString()].SetValue(field, value);
}
private Dictionary<string, ReportGraph> _graphs = new Dictionary<string, ReportGraph>();
protected void AddGraph(ReportGraph graph) { _graphs.Add(graph.Id, graph); graph.PropertyChanged += new PropertyChangedEventHandler(graph_PropertyChanged); }
protected ReportGraph GetGraph(string id) { return _graphs[id]; }
public string GetValueTrunc2Places(KnownGraphs graph, string id, GraphChannel.Fields field)
{
return _graphs[graph.ToString()].GetValueTrunc2Places(id, field);
}
public string GetValue(KnownGraphs graph, string id, GraphChannel.Fields field)
{
return _graphs[graph.ToString()].GetValue(id, field);
}
protected void graph_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
ReportGraph graph = sender as ReportGraph;
OnPropertyChanged("Graph-x-"+graph.Id + "-x-" + e.PropertyName);
}
public string GetValue(KnownGraphs graph, ReportGraph.Fields field)
{
return _graphs[graph.ToString()].GetValue(field);
}
public virtual void DrawGraph(KnownGraphs graph, C1.Win.C1Chart.C1Chart chart)
{
DrawGraph(graph.ToString(), chart);
}
public void DrawGraph(string id, C1.Win.C1Chart.C1Chart chart)
{
_graphs[id].Draw(chart);
}
protected void DrawGraph(KnownGraphs graph)
{
_graphs[graph.ToString()].Draw();
}
public double[] GetXPlot(KnownGraphs graph, string id)
{
return _graphs[graph.ToString()].GetXPlot(id);
}
public double[] GetYPlot(KnownGraphs graph, string id)
{
return _graphs[graph.ToString()].GetYPlot(id);
}
public enum KnownGraphs
{
LWR_LEG_TRL_Acceleration,
LWR_LEG_TRL_BendingAngle,
LWR_LEG_TRL_ShearAngle,
HEAD_ResultantAcceleration,
HEAD_Acceleration,
HEAD_StrokeDisplacement,
ARS_ARS,
ARS_Acceleration,
FLEX_TIBIA,
FLEX_MCL,
FLEX_ACLPCL,
FLEX_LCL,
FLEX_FEMUR,
UPRLEG_Force,
UPRLeg_Moment,
FLEX_CALTibia1,
FLEX_CALTibia2,
FLEX_CALTibia3,
FLEX_CALTibia4,
FLEX_CALMCL,
FLEX_CALACL,
FLEX_CALPCL,
LWR_LEG_TRL_BendingDisplacement,
LWR_LEG_TRL_ShearDisplacement
}
/// <summary>
/// we maintain a link to the owning test report
/// we do this so we can get access to the Test property, which
/// contains the information on what event we are actually operating on
/// </summary>
protected PedestrianAndHeadTest _testParent;
public ReportBase(PedestrianAndHeadTest parent)
{
_testParent = parent;
//mostly we just want to be notified if our parent changes tests ...
_testParent.PropertyChanged += new PropertyChangedEventHandler(_testParent_PropertyChanged);
InitializeProperties();
InitializeGraphs();
}
/// <summary>
/// this is function gets called whenever the parent pedestrian and head report changes tests.
/// the default base class does nothing, but our descendants are free to do with it as they please
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void _testParent_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Test":
var enumerator = _graphs.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Value.Clear(_testParent.Test);
}
enumerator = _graphs.GetEnumerator();
while (enumerator.MoveNext())
{
enumerator.Current.Value.SetDefaults(_testParent.Test);
enumerator.Current.Value.SetCFC(ChannelFilterClass, this);
}
if (null != _testParent.Test) { SetValue(PedestrianAndHeadTest.Fields.TestDate.ToString(), _testParent.Test.CreationTime.Ticks.ToString()); }
break;
}
}
/// <summary>
/// list of all properties for the report
/// note it's private, so that it forces descendants through the accessor methods where we have more
/// control
/// </summary>
private Dictionary<string, ReportProperty> _properties = new Dictionary<string, ReportProperty>();
protected virtual void InitializeProperties()
{
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestNumber.ToString(), "試験NO", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestDate.ToString(), "試験実施日", null, typeof(DateTime)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.CarName.ToString(), "車名", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.Model.ToString(), "型式", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestTemperature.ToString(), "試験温度", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString(), "測定点", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString(), "衝突速度", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorId.ToString(), "インパクタID", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorType.ToString(), "インパクタ種類", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString(), "インパクタ重量", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString(), "試験担当者", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.And1.ToString(), "予備1", null, typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.And2.ToString(), "予備2", null, typeof(string)));
List<string> filters = new List<string>();
SensorDB.FilterClass.FilterClassType[] filtertypes = Enum.GetValues(typeof(SensorDB.FilterClass.FilterClassType)).Cast<SensorDB.FilterClass.FilterClassType>().ToArray();
foreach (var ft in filtertypes)
{
switch (ft)
{
case DTS.SensorDB.FilterClass.FilterClassType.AdHoc: break;
default: filters.Add((new SensorDB.FilterClass(ft)).ToString()); break;
}
}
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.FrequencyClass.ToString(), "周波数クラス", filters.ToArray(), typeof(string)));
AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), "Time", new string[] { "s", "ms" }, typeof(string)));
SetValue(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), "s");
}
protected virtual void InitializeGraphs() { ;}
/// <summary>
/// sets a value for a property (and notifies any listeners of the change)
/// </summary>
/// <param name="field"></param>
/// <param name="value"></param>
public void SetValue(string field, string value)
{
if (_properties[field].Value == value) { return; }
_properties[field].SetValue(value);
switch (field)
{
case "TimeUnits":
foreach (var g in _graphs) { g.Value.TimeUnits = value; }
break;
}
OnPropertyChanged(field);
}
/// <summary>
/// returns the value for a property
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
public string GetValue(string field)
{
if (!_properties.ContainsKey(field) || string.IsNullOrEmpty(_properties[field].Value)) { return ""; }
else { return _properties[field].Value; }
}
/// <summary>
/// returns all possible values for a property (or null if the user must manually enter a value)
/// </summary>
/// <param name="field"></param>
/// <returns></returns>
protected string[] GetPossibleValues(string field) { return _properties[field].GetAvailableValues(); }
/// <summary>
/// sets the possible values for a property
/// </summary>
/// <param name="field"></param>
/// <param name="values"></param>
protected void SetPossibleValues(string field, string[] values)
{
_properties[field].SetAvailableValues(values);
if (null != values && values.Length == 1)
{
_properties[field].SetValue(values[0]);
}
}
/// <summary>
/// adds a new property
/// this enables descendants to have their own unique properties
/// </summary>
/// <param name="p"></param>
protected void AddProperty(ReportProperty p) { _properties.Add(p.Id, p); }
/// <summary>
/// the known report types, we can make this more generic in the future?
/// maybe just a name?
/// </summary>
public enum ReportTypes
{
Head,
UPRLeg,
LWRLegTRL,
LWRLegFlex,
LWRLegARS
}
public string GetName()
{
switch (GetReportType())
{
case ReportTypes.Head: return "HEAD";
case ReportTypes.LWRLegARS: return "LWR LEG(ARS)";
case ReportTypes.LWRLegFlex: return "LWR LEG(FLEX)";
case ReportTypes.LWRLegTRL: return "LWR LEG(TRL)";
case ReportTypes.UPRLeg: return "UPR LEG";
}
throw new Exception("uknown report type: " + GetReportType().ToString());
}
public abstract ReportTypes GetReportType();
/// <summary>
/// indicates whether this report is currently in use in the
/// pedestrian and head report (selected to export)
/// </summary>
protected bool _bInUse = false;
public bool InUse
{
get { return _bInUse; }
set { SetProperty(ref _bInUse, value, "InUse"); }
}
/// <summary>
/// all these properties come directly from the Pedestrian and Head Safety report sample xlsx ..
/// </summary>
public string TestNumber
{
get { return GetValue(PedestrianAndHeadTest.Fields.TestNumber.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.TestNumber.ToString(), value); }
}
/// <summary>
/// this one is the only one that is a little tricky,
/// we move to and from longs to avoid globalization issues ...
/// </summary>
public DateTime TestDate
{
get { return new DateTime(long.Parse(GetValue(PedestrianAndHeadTest.Fields.TestDate.ToString()))); }
set { SetValue(PedestrianAndHeadTest.Fields.TestDate.ToString(), value.Ticks.ToString()); }
}
public string CarName
{
get { return GetValue(PedestrianAndHeadTest.Fields.CarName.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.CarName.ToString(), value); }
}
public string Model
{
get { return GetValue(PedestrianAndHeadTest.Fields.Model.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.Model.ToString(), value); }
}
public string TestTemperature
{
get { return GetValue(PedestrianAndHeadTest.Fields.TestTemperature.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.TestTemperature.ToString(), value); }
}
public string MeasurementPoint
{
get { return GetValue(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString(), value); }
}
public string CollisionSpeed
{
get { return GetValue(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString(), value); }
}
public string ImpactorID
{
get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorId.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.ImpactorId.ToString(), value); }
}
public string ImpactorType
{
get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorType.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.ImpactorType.ToString(), value); }
}
public string StudyPersonnel
{
get { return GetValue(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString(), value); }
}
public string And1
{
get { return GetValue(PedestrianAndHeadTest.Fields.And1.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.And1.ToString(), value); }
}
public string And2
{
get { return GetValue(PedestrianAndHeadTest.Fields.And2.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.And2.ToString(), value); }
}
public string[] GetAvailableTimeUnits() { return _properties[PedestrianAndHeadTest.Fields.TimeUnits.ToString()].GetAvailableValues(); }
public string TimeUnits
{
get { return _properties[PedestrianAndHeadTest.Fields.TimeUnits.ToString()].Value; }
set { SetValue(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), value); }
}
public string ImpactorWeight
{
get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString()); }
set { SetValue(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString(), value); }
}
public virtual string ChannelFilterClass
{
get { return GetValue(PedestrianAndHeadTest.Fields.FrequencyClass.ToString()); }
set
{
SetValue(PedestrianAndHeadTest.Fields.FrequencyClass.ToString(), value);
var e = _graphs.GetEnumerator();
while (e.MoveNext()) { e.Current.Value.SetCFC(value,this); }
}
}
public string[] GetImpactorTypes()
{
return GetPossibleValues(PedestrianAndHeadTest.Fields.ImpactorType.ToString());
}
public string[] GetAvailableFilterTypes()
{
return GetPossibleValues(PedestrianAndHeadTest.Fields.FrequencyClass.ToString());
}
public MeasurementUnit GetUnits(KnownGraphs graph)
{
return GetGraph(graph.ToString()).GetChannelUnit();
}
public void SetUnits(KnownGraphs graph, MeasurementUnit units)
{
GetGraph(graph.ToString()).SetChannelUnit(units);
DrawGraph(graph, GetGraph(graph.ToString()).Chart);
}
public MeasurementUnit[] GetAvailableUnits(KnownGraphs graph)
{
return GetGraph(graph.ToString()).GetChannelUnits();
}
public ReviewTestChannel GetChannel(KnownGraphs graph, string id)
{
return GetGraph(graph.ToString()).GetReviewTestChannel(id);
}
public void SetChannel(KnownGraphs graph, string id, ReviewTestChannel channel)
{
GetGraph(graph.ToString()).SetReviewTestChannel(id, channel);
GetGraph(graph.ToString()).SetCFC(ChannelFilterClass, this);
}
public ReviewTestChannel[] GetAvailableChannels(KnownGraphs graph, string id)
{
return GetGraph(graph.ToString()).GetAvailableChannels(id, _testParent.Test);
}
public void ToStringOutput(ref System.Xml.XmlWriter xt)
{
xt.WriteStartElement("Report");
//xt.WriteStartElement("ReportType");
xt.WriteElementString("ReportType", GetReportType().ToString());
xt.WriteElementString("InUse", InUse.ToString());
var e = _properties.GetEnumerator();
while (e.MoveNext())
{
try
{
PedestrianAndHeadTest.Fields field = (PedestrianAndHeadTest.Fields)Enum.Parse(typeof(PedestrianAndHeadTest.Fields), e.Current.Value.Id);
switch (field)
{
case PedestrianAndHeadTest.Fields.TestNumber:
continue;
case PedestrianAndHeadTest.Fields.TestDate:
continue;
case PedestrianAndHeadTest.Fields.TestTemperature:
continue;
case PedestrianAndHeadTest.Fields.CollisionSpeed:
continue;
}
}
catch (System.Exception) { }
xt.WriteElementString(e.Current.Value.Id, e.Current.Value.Value);
}
this.GetReportType();
xt.WriteEndElement();
}
}
}