chore: 初始化解放动力大柴MES管理站点
This commit is contained in:
300
App_code/drawchart/DrawPareto.cs
Normal file
300
App_code/drawchart/DrawPareto.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Web.UI.DataVisualization.Charting;
|
||||
using System.Collections;
|
||||
|
||||
/// <summary>
|
||||
///DrawPareto 的摘要说明
|
||||
/// </summary>
|
||||
public class DrawPareto
|
||||
{
|
||||
public DrawPareto()
|
||||
{
|
||||
//
|
||||
//TODO: 在此处添加构造函数逻辑
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Number of class intervals the data range is devided in.
|
||||
/// This property only has affect when "SegmentIntervalWidth" is
|
||||
/// set to double.NaN.
|
||||
/// </summary>
|
||||
public int SegmentIntervalNumber = 20;
|
||||
|
||||
/// <summary>
|
||||
/// Histogram class interval width. Setting this value to "double.NaN"
|
||||
/// will result in automatic width calculation based on the data range
|
||||
/// and number of required interval specified in "SegmentIntervalNumber".
|
||||
/// </summary>
|
||||
public double SegmentIntervalWidth = double.NaN;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that percent frequency should be shown on the right axis
|
||||
/// </summary>
|
||||
public bool ShowPercentOnSecondaryYAxis = true;
|
||||
|
||||
|
||||
public void CreatePareto(
|
||||
Chart chartControl,
|
||||
string dataSeriesName,
|
||||
string histogramSeriesName)
|
||||
{
|
||||
// Validate input
|
||||
if (chartControl == null)
|
||||
{
|
||||
throw (new ArgumentNullException("chartControl"));
|
||||
}
|
||||
if (chartControl.Series.IndexOf(dataSeriesName) < 0)
|
||||
{
|
||||
throw (new ArgumentException("Series with name'" + dataSeriesName + "' was not found.", "dataSeriesName"));
|
||||
}
|
||||
|
||||
// Make data series invisible
|
||||
chartControl.Series[dataSeriesName].Enabled = false;
|
||||
|
||||
// Check if histogram series exsists
|
||||
Series histogramSeries = null;
|
||||
if (chartControl.Series.IndexOf(histogramSeriesName) < 0)
|
||||
{
|
||||
// Add new series
|
||||
histogramSeries = chartControl.Series.Add(histogramSeriesName);
|
||||
|
||||
// Set new series chart type and other attributes
|
||||
histogramSeries.ChartType = SeriesChartType.Column;
|
||||
histogramSeries.BorderColor = Color.Black;
|
||||
histogramSeries.BorderWidth = 1;
|
||||
histogramSeries.BorderDashStyle = ChartDashStyle.Solid;
|
||||
}
|
||||
else
|
||||
{
|
||||
histogramSeries = chartControl.Series[histogramSeriesName];
|
||||
histogramSeries.Points.Clear();
|
||||
}
|
||||
|
||||
// Get data series minimum and maximum values
|
||||
double minValue = double.MaxValue;
|
||||
double maxValue = double.MinValue;
|
||||
int pointCount = 0;
|
||||
foreach (DataPoint dataPoint in chartControl.Series[dataSeriesName].Points)
|
||||
{
|
||||
// Process only non-empty data points
|
||||
if (!dataPoint.IsEmpty)
|
||||
{
|
||||
if (dataPoint.YValues[0] > maxValue)
|
||||
{
|
||||
maxValue = dataPoint.YValues[0];
|
||||
}
|
||||
if (dataPoint.YValues[0] < minValue)
|
||||
{
|
||||
minValue = dataPoint.YValues[0];
|
||||
}
|
||||
++pointCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate interval width if it's not set
|
||||
if (double.IsNaN(this.SegmentIntervalWidth))
|
||||
{
|
||||
this.SegmentIntervalWidth = (maxValue - minValue) / SegmentIntervalNumber;
|
||||
this.SegmentIntervalWidth = RoundInterval(this.SegmentIntervalWidth);
|
||||
}
|
||||
|
||||
// Round minimum and maximum values
|
||||
minValue = Math.Floor(minValue / this.SegmentIntervalWidth) * this.SegmentIntervalWidth;
|
||||
maxValue = Math.Ceiling(maxValue / this.SegmentIntervalWidth) * this.SegmentIntervalWidth;
|
||||
|
||||
// Create histogram series points
|
||||
double currentPosition = minValue;
|
||||
for (currentPosition = minValue; currentPosition <= maxValue; currentPosition += this.SegmentIntervalWidth)
|
||||
{
|
||||
// Count all points from data series that are in current interval
|
||||
int count = 0;
|
||||
foreach (DataPoint dataPoint in chartControl.Series[dataSeriesName].Points)
|
||||
{
|
||||
if (!dataPoint.IsEmpty)
|
||||
{
|
||||
double endPosition = currentPosition + this.SegmentIntervalWidth;
|
||||
if (dataPoint.YValues[0] >= currentPosition &&
|
||||
dataPoint.YValues[0] < endPosition)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
// Last segment includes point values on both segment boundaries
|
||||
else if (endPosition >= maxValue)
|
||||
{
|
||||
if (dataPoint.YValues[0] >= currentPosition &&
|
||||
dataPoint.YValues[0] <= endPosition)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add data point into the histogram series
|
||||
//histogramSeries.Points.AddXY("", count);
|
||||
histogramSeries.Points.AddY( count);
|
||||
|
||||
}
|
||||
|
||||
histogramSeries.Sort(PointSortOrder.Descending);
|
||||
|
||||
// Adjust series attributes
|
||||
histogramSeries["PointWidth"] = "1";
|
||||
|
||||
// Adjust chart area
|
||||
ChartArea chartArea = chartControl.ChartAreas[histogramSeries.ChartArea];
|
||||
chartArea.AxisY.Title = "频数";
|
||||
//chartArea.AxisX.Minimum = minValue;
|
||||
//chartArea.AxisX.Maximum = maxValue;
|
||||
|
||||
// Set axis interval based on the histogram class interval
|
||||
// and do not allow more than 10 labels on the axis.
|
||||
double axisInterval = this.SegmentIntervalWidth;
|
||||
while ((maxValue - minValue) / axisInterval > 10.0)
|
||||
{
|
||||
axisInterval *= 2.0;
|
||||
}
|
||||
chartArea.AxisX.Interval = axisInterval;
|
||||
|
||||
// Set chart area secondary Y axis
|
||||
chartArea.AxisY2.Enabled = AxisEnabled.Auto;
|
||||
if (this.ShowPercentOnSecondaryYAxis)
|
||||
{
|
||||
chartArea.RecalculateAxesScale();
|
||||
|
||||
chartArea.AxisY2.Enabled = AxisEnabled.True;
|
||||
chartArea.AxisY2.LabelStyle.Format = "P0";
|
||||
chartArea.AxisY2.MajorGrid.Enabled = false;
|
||||
chartArea.AxisY2.Title = "Percent of Total";
|
||||
|
||||
chartArea.AxisY2.Minimum = 0;
|
||||
chartArea.AxisY2.Maximum = chartArea.AxisY.Maximum / (pointCount / 100.0);
|
||||
double minStep = (chartArea.AxisY2.Maximum > 20.0) ? 5.0 : 1.0;
|
||||
chartArea.AxisY2.Interval = Math.Ceiling((chartArea.AxisY2.Maximum / 5.0 / minStep)) * minStep;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method which rounds specified axsi interval.
|
||||
/// </summary>
|
||||
/// <param name="interval">Calculated axis interval.</param>
|
||||
/// <returns>Rounded axis interval.</returns>
|
||||
public double RoundInterval(double interval)
|
||||
{
|
||||
// If the interval is zero return error
|
||||
if (interval == 0.0)
|
||||
{
|
||||
throw (new ArgumentOutOfRangeException("interval", "Interval can not be zero."));
|
||||
}
|
||||
|
||||
// If the real interval is > 1.0
|
||||
double step = -1;
|
||||
double tempValue = interval;
|
||||
while (tempValue > 1.0)
|
||||
{
|
||||
step++;
|
||||
tempValue = tempValue / 10.0;
|
||||
if (step > 1000)
|
||||
{
|
||||
throw (new InvalidOperationException("Auto interval error due to invalid point values or axis minimum/maximum."));
|
||||
}
|
||||
}
|
||||
|
||||
// If the real interval is < 1.0
|
||||
tempValue = interval;
|
||||
if (tempValue < 1.0)
|
||||
{
|
||||
step = 0;
|
||||
}
|
||||
|
||||
while (tempValue < 1.0)
|
||||
{
|
||||
step--;
|
||||
tempValue = tempValue * 10.0;
|
||||
if (step < -1000)
|
||||
{
|
||||
throw (new InvalidOperationException("Auto interval error due to invalid point values or axis minimum/maximum."));
|
||||
}
|
||||
}
|
||||
|
||||
double tempDiff = interval / Math.Pow(10.0, step);
|
||||
if (tempDiff < 3.0)
|
||||
{
|
||||
tempDiff = 2.0;
|
||||
}
|
||||
else if (tempDiff < 7.0)
|
||||
{
|
||||
tempDiff = 5.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempDiff = 10.0;
|
||||
}
|
||||
|
||||
// Make a correction of the real interval
|
||||
return tempDiff * Math.Pow(10.0, step);
|
||||
}
|
||||
|
||||
public void MakeParetoChart(Chart chart, string srcSeriesName, string destSeriesName)
|
||||
{
|
||||
|
||||
// get name of the ChartAre of the source series
|
||||
string strChartArea = chart.Series[srcSeriesName].ChartArea;
|
||||
|
||||
// ensure the source series is a column chart type
|
||||
chart.Series[srcSeriesName].ChartType = SeriesChartType.Column;
|
||||
|
||||
// sort the data in the series to be by values in descending order
|
||||
chart.DataManipulator.Sort(PointSortOrder.Descending, srcSeriesName);
|
||||
|
||||
// find the total of all points in the source series
|
||||
double total = 0.0;
|
||||
foreach (DataPoint pt in chart.Series[srcSeriesName].Points)
|
||||
total += pt.YValues[0];
|
||||
|
||||
// set the max value on the primary axis to total
|
||||
chart.ChartAreas[strChartArea].AxisY.Maximum = total;
|
||||
|
||||
// create the destination series and add it to the chart
|
||||
Series destSeries = new Series(destSeriesName);
|
||||
chart.Series.Add(destSeries);
|
||||
|
||||
// ensure the destination series is a Line or Spline chart type
|
||||
destSeries.ChartType = SeriesChartType.Line;
|
||||
|
||||
destSeries.BorderWidth = 3;
|
||||
|
||||
// assign the series to the same chart area as the column chart
|
||||
destSeries.ChartArea = chart.Series[srcSeriesName].ChartArea;
|
||||
|
||||
// assign this series to use the secondary axis and set it maximum to be 100%
|
||||
destSeries.YAxisType = AxisType.Secondary;
|
||||
chart.ChartAreas[strChartArea].AxisY2.Maximum = 100;
|
||||
|
||||
// locale specific percentage format with no decimals
|
||||
chart.ChartAreas[strChartArea].AxisY2.LabelStyle.Format = "0.#";
|
||||
|
||||
// turn off the end point values of the primary X axis
|
||||
chart.ChartAreas[strChartArea].AxisX.LabelStyle.IsEndLabelVisible = false;
|
||||
|
||||
// for each point in the source series find % of total and assign to series
|
||||
double percentage = 0.0;
|
||||
|
||||
foreach (DataPoint pt in chart.Series[srcSeriesName].Points)
|
||||
{
|
||||
percentage += (pt.YValues[0] / total * 100.0);
|
||||
//Chart1.Series["Default"].Points.AddXY(pt.XValue,Math.Round(percentage, 2));
|
||||
destSeries.Points.Add(Math.Round(percentage, 2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user