using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using System.Windows.Markup; using System.Xaml.Schema; namespace DataManager { public partial class NavChart : Form { private string fundId; private DataTable nav; private DataTable indexNav; private DateTime oldestPriceDate = new DateTime(2000,1,1); private DateTime latestPriceDate = DateTime.Today; public NavChart(string fundId, DataTable nav) { InitializeComponent(); this.fundId = fundId; this.nav = nav; InitializeData(); } private void InitializeData() { dtpStartDate.Checked = true; if (nav != null && nav.Rows.Count > 0) { oldestPriceDate = DateTime.Parse(nav.Select("", "price_date")[0]["price_date"].ToString()); if (oldestPriceDate <= new DateTime(1990, 1, 1)) oldestPriceDate = new DateTime(1990, 1, 1); latestPriceDate = DateTime.Parse(nav.Select("", "price_date")[nav.Rows.Count - 1]["price_date"].ToString()); dtpStartDate.Value = oldestPriceDate; } dtpEndDate.Checked = true; dtpEndDate.Value = DateTime.Today; cmbTimePeriod.SelectedIndex = 0; if (!string.IsNullOrEmpty(fundId)) { cmbBenchmark.DataSource = DataAccess.Get_dm_fund_benchmark(fundId); } else { DataTable dt = new DataTable(); dt.Columns.Add("index_id", typeof(string)); dt.Columns.Add("index_short_name", typeof(string)); dt.Rows.Add("IN00000008", "沪深300"); cmbBenchmark.DataSource = dt; } cmbBenchmark.DisplayMember = "index_short_name"; cmbBenchmark.ValueMember = "index_id"; cmbBenchmark.SelectedIndex = 0; chtNav.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.LightGray; chtNav.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray; chtNav.ChartAreas[0].AxisY.MinorGrid.Enabled = true; chtNav.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray; chtNav.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot; chtNav.ChartAreas[0].AxisY2.MinorGrid.Enabled = false; chtNav.ChartAreas[0].AxisY2.MajorGrid.LineColor = Color.LightGray; // Y 轴最大最小值自适应 chtNav.ChartAreas[0].AxisY.IsStartedFromZero = false; chtNav.ChartAreas[0].AxisY2.IsStartedFromZero = false; Series seriesFund = chtNav.Series[0]; seriesFund.ChartType = SeriesChartType.Line; seriesFund.MarkerStyle = MarkerStyle.Circle; seriesFund.LegendText = "分红再投净值"; BindChartData(nav, seriesFund); Series seriesIndex = chtNav.Series[1]; seriesIndex.ChartType = SeriesChartType.Line; seriesIndex.YAxisType = AxisType.Secondary; seriesIndex.LegendText = cmbBenchmark.GetItemText(cmbBenchmark.SelectedItem); string indexId = cmbBenchmark.SelectedValue.ToString(); indexNav = DataAccess.Get_Nav(indexId, oldestPriceDate, latestPriceDate); BindChartData(indexNav, seriesIndex); } private DataTable FilterDate(DataTable data, DateTime startDate, DateTime endDate) { DataTable dt = null; if (startDate > endDate) { MessageBox.Show("起始日不能大于截止日哦"); return null; } if (data != null && data.Rows.Count > 0) { string expression = "price_date <= #" + endDate.ToString() + "# and price_date >= #" + startDate.ToString() + "#"; DataRow[] rows = data.Select(expression, "price_date"); if (rows != null && rows.Length > 0) dt = rows.CopyToDataTable(); } return dt; } private void BindChartData(DataTable data, Series series) { if (data != null && data.Rows.Count > 0) series.Points.DataBind(data.AsEnumerable(), "price_date", "cumulative_nav", ""); } // 这个事件不好用,但Value_Changed会深度死机 private void dtpEndDate_Leave(object sender, EventArgs e) { } private void btnDateChanged_Click(object sender, EventArgs e) { DateTime startDate = dtpStartDate.Value; if (dtpStartDate.Checked == false) startDate = DateTime.MinValue; DateTime endDate = dtpEndDate.Value; if (dtpEndDate.Checked == false) endDate = DateTime.MaxValue; BindChartData(FilterDate(nav, startDate, endDate), chtNav.Series["fund"]); BindChartData(FilterDate(indexNav, startDate, endDate), chtNav.Series["index"]); } private void cmbTimePeriod_SelectedIndexChanged(object sender, EventArgs e) { DateTime startDate = new DateTime(); DateTime endDate = DateTime.Today; switch (cmbTimePeriod.SelectedIndex) { case 0: startDate = oldestPriceDate; break; case 1: startDate = endDate.AddMonths(-3); break; case 2: startDate = endDate.AddYears(-1); break; case 3: startDate = endDate.AddYears(-2); break; case 4: startDate = endDate.AddYears(-3); break; case 5: startDate = endDate.AddYears(-5); break; case 6: startDate = endDate.AddYears(-10); break; default: startDate = oldestPriceDate; break; } dtpStartDate.Value = startDate; dtpEndDate.Value = endDate; BindChartData(FilterDate(nav, startDate, endDate), chtNav.Series["fund"]); BindChartData(FilterDate(indexNav, startDate, endDate), chtNav.Series["index"]); } private void cmbBenchmark_SelectedIndexChanged(object sender, EventArgs e) { string indexId = cmbBenchmark.SelectedValue.ToString(); if(indexId.Length != 10) return; indexNav = DataAccess.Get_Nav(indexId, oldestPriceDate, latestPriceDate); DateTime startDate = DateTime.Parse(dtpStartDate.Text); DateTime endDate = DateTime.Parse(dtpEndDate.Text); chtNav.Series["index"].LegendText = cmbBenchmark.GetItemText(cmbBenchmark.SelectedItem); ; BindChartData(FilterDate(indexNav, startDate, endDate), chtNav.Series["index"]); } } }