1506 lines
62 KiB
C#
1506 lines
62 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Consulenza.ReportWriter.Business.Entity;
|
|
using ceTe.DynamicPDF;
|
|
using Dundas.Charting.WebControl;
|
|
using Consulenza.ReportCommon;
|
|
using System;
|
|
using Consulenza.ReportWriter.Business.OBJ_PDF;
|
|
using System.Web;
|
|
using ceTe.DynamicPDF.PageElements;
|
|
using Consulenza.ReportWriter.Business;
|
|
using Consulenza.ReportWriter.Business.CUSTOM_PDF.ConsulenzaUnica;
|
|
|
|
namespace Consulenza.ReportWriter.Business.CHART_PDF
|
|
{
|
|
public class CombinationPDF : ChartPDF
|
|
{
|
|
private ReportEnvironment reportEnvironment;
|
|
|
|
private double _maximumAxisY = 0;
|
|
private double _minimumAxisY = 0;
|
|
private double _maximumAxisX = 0;
|
|
private double _minimumAxisX = 0;
|
|
private double _intervalY = 0;
|
|
private double _intervalX = 0;
|
|
private float _legendYOffset = 0;
|
|
// Variabili usate quando XValueType = Date o DateTime
|
|
private DateTime _minimumDate = DateTime.Today;
|
|
private DateTime _maximumDate = DateTime.Today;
|
|
private int _intervalDays = 0;
|
|
private int _intervalMonths = 0;
|
|
private float _chartBaseHeight = 0;
|
|
private float _chartBaseWidth = 0;
|
|
private bool _removeWhiteSpacesY = false;
|
|
private bool _showZeroInLabel = false;
|
|
|
|
|
|
#region Field
|
|
public bool EqualDateLabelDistanceAxisX { get; set; }
|
|
/// <summary>
|
|
/// bool che indica se mostrare la legenda. Di default = false.
|
|
/// </summary>
|
|
|
|
public float AxisYMinimumValueOffset { get; set; }
|
|
public bool ShowLegend { get; set; }
|
|
|
|
public bool CalculateCustomIntegerLabelsAxisY { get; set; }
|
|
|
|
public void SetReportEnvironment(ReportEnvironment reportEnvironment)
|
|
{
|
|
this.reportEnvironment = reportEnvironment;
|
|
}
|
|
public bool showZeroInLabel {
|
|
get { return _showZeroInLabel; }
|
|
set { _showZeroInLabel = value; }
|
|
}
|
|
public bool RemoveWhiteSpacesY
|
|
{
|
|
get
|
|
{
|
|
return _removeWhiteSpacesY;
|
|
}
|
|
set
|
|
{
|
|
_removeWhiteSpacesY = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Lista di interi che rappresentano le larghezze personalizzabili delle colonne della tabella che compone la Leggenda.
|
|
/// Colonna1: Immagine, Colonna2: Spazio, Colonna3: Testo.
|
|
/// Di default = (20,15,125)
|
|
/// </summary>
|
|
public List<int> LegendWidthColumns { get; set; }
|
|
|
|
public float LegendYOffset
|
|
{
|
|
get
|
|
{
|
|
return _legendYOffset;
|
|
}
|
|
set
|
|
{
|
|
_legendYOffset = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera l'altezza del simbolo della colonna1 della tabella che compone la legenda.
|
|
/// Di default= 10.
|
|
/// </summary>
|
|
public float LegendSymbolHeight { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il delta Y (intesto come spostamento in alto in basso della Y del simbolo della legenda).
|
|
/// Di default=4.
|
|
/// </summary>
|
|
public float LegendSymbolDeltaY { get; set; }
|
|
|
|
public float InnerChartDeltaY { get; set; }
|
|
|
|
public float ChartBaseHeight
|
|
{
|
|
get
|
|
{
|
|
return _chartBaseHeight;
|
|
}
|
|
set
|
|
{
|
|
ChartBase.Height = (System.Web.UI.WebControls.Unit)value;
|
|
_chartBaseHeight = value;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public float? AxisXMaximum { get; set; }
|
|
|
|
public float? AxisXMinimum { get; set; }
|
|
|
|
public float ChartBaseWidth
|
|
{
|
|
get
|
|
{
|
|
return _chartBaseWidth;
|
|
}
|
|
set
|
|
{
|
|
ChartBase.Width = (System.Web.UI.WebControls.Unit)value;
|
|
_chartBaseWidth = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Imposta o recupera il delta X (intesto come spostamento a destra o sinistra della X della legenda).
|
|
/// Di default=0.
|
|
/// </summary>
|
|
public float LegendDeltaX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il font size del testo della legenda.
|
|
/// Di default= 8.
|
|
/// </summary>
|
|
public int LegendFontSizeText { get; set; }
|
|
|
|
/// <summary>
|
|
/// bool che indica se mostrare il border top. Di default = false.
|
|
/// </summary>
|
|
public bool BorderLineTop { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera la X di BorderLineTop quando BorderLineTop = true.
|
|
/// </summary>
|
|
public float BorderLineX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera la Width di BorderLineTop quando BorderLineTop = true.
|
|
/// </summary>
|
|
public float BorderLineWidth { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostare la linea sull'asse y in corrispondeza dell'intervallo.
|
|
/// Di default = false.
|
|
/// </summary>
|
|
public bool MinorGridAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il margine nell'asse y.
|
|
/// Di default = 7.
|
|
/// </summary>
|
|
public float MarginAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostrare la linea dell'asse Y.
|
|
/// Di default = True.
|
|
/// </summary>
|
|
public bool ShowLineAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostrare la linea dell'asse X.
|
|
/// Di default = False.
|
|
/// </summary>
|
|
public bool ShowLineAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il numero di intervalli per l'asse Y.
|
|
/// Di default = 4.
|
|
/// </summary>
|
|
public int IntervalNumberAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il tipo di formato delle etichette dell'asse Y.
|
|
/// Di default = FormatType.Intero
|
|
/// </summary>
|
|
public FormatType LabelFormatAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il tipo di formato delle etichette dell'asse X.
|
|
/// Di default = FormatType.Intero
|
|
/// </summary>
|
|
public FormatType LabelFormatAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostrare le label dell'asse Y.
|
|
/// Di default = True.
|
|
/// </summary>
|
|
public bool ShowLabelAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostrare le label dell'asse X.
|
|
/// Di default = True.
|
|
/// </summary>
|
|
public bool ShowLabelAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il numero di intervalli per l'asse X.
|
|
/// Di default = 4.
|
|
/// </summary>
|
|
public int IntervalNumberAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica che l'asse X partirà da 0.
|
|
/// Di default = false.
|
|
/// </summary>
|
|
public bool StartFromZeroAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica che l'asse Y partirà da 0.
|
|
/// Di default = false.
|
|
/// </summary>
|
|
public bool StartFromZeroAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il nome dell'immagine di sfondo del grafico.
|
|
/// Di default = string.empty (nessuna immagine).
|
|
/// </summary>
|
|
public string BackImage { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera il colore di sfondo del grafico.
|
|
/// Di default = Bianco.
|
|
/// </summary>
|
|
public ColorPDF BackColor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera l'indicatore dell'asse Y.
|
|
/// Di default null = nessuna renderizzazione.
|
|
/// </summary>
|
|
public CombinationPDFIndicator? IndicatorAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera l'indicatore dell'asse X.
|
|
/// Di default null = nessuna renderizzazione.
|
|
/// </summary>
|
|
public CombinationPDFIndicator? IndicatorAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera la lista di label personalizzate dell'asse Y
|
|
/// </summary>
|
|
public List<CombinationPDFCustomLabel> CustomLabelAxisY { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera la lista di label personalizzate dell'asse X
|
|
/// </summary>
|
|
public List<CombinationPDFCustomLabel> CustomLabelAxisX { get; set; }
|
|
|
|
public bool ShowCustomLabelsAxisX { get; set; }
|
|
/// <summary>
|
|
/// Imposta o recupera il valore massimo dell'asse Y.
|
|
/// Quando è 0 il valore massimo è preso tra i valori aggiunti ai Points delle Series.
|
|
/// Di default = 0.
|
|
/// </summary>
|
|
public double MaximumValueAxisY { get; set; }
|
|
|
|
|
|
public double MinimumValueAxisY { get; set; }
|
|
|
|
public bool DontCalculateMaxAndMinAxisY { get; set; }
|
|
/// <summary>
|
|
/// Imposta o recupera il valore massimo dell'asse X.
|
|
/// Quando è 0 il valore massimo è preso tra i valori aggiunti ai Points delle Series.
|
|
/// Di default = 0.
|
|
/// </summary>
|
|
public double MaximumValueAxisX { get; set; }
|
|
|
|
/// <summary>
|
|
/// Imposta o recupera un bool che indica se mostrare lo 0 sull'asse delle Y.
|
|
/// di default= false.
|
|
/// </summary>
|
|
public bool ShowMarginX { get; set; }
|
|
|
|
///// <summary>
|
|
///// Imposta o recupera un bool che indica se mostrare un margine (definito da dundas) e l'inizio delle barre sull'asse X.
|
|
///// Di default= false.
|
|
///// </summary>
|
|
//public bool ShowMarginX { get; set; }
|
|
|
|
///// <summary>
|
|
///// Imposta o recupera un bool che indica se mostrare un margine (definito da dundas) e l'inizio delle barre sull'asse Y.
|
|
///// Di default= false.
|
|
///// </summary>
|
|
//public bool ShowMarginY { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region Costruttori
|
|
|
|
/// <summary>
|
|
/// Costruttore
|
|
/// </summary>
|
|
public CombinationPDF()
|
|
{
|
|
ObjectType = ObjectTypePdf.CHART;
|
|
ChartType = ChartTypePdf.COMBINATION;
|
|
ChartBase.ChartAreas.Add("Default");
|
|
|
|
BackColor = ColorPDF.Bianco;
|
|
|
|
// Imposto la ChartAreas di default in modalidtà 3D
|
|
ChartBase.ChartAreas["Default"].Area3DStyle.Enable3D = true;
|
|
ChartBase.ChartAreas["Default"].Area3DStyle.XAngle = 5;
|
|
|
|
// Legenda disabilitata
|
|
ChartBase.Legend.Enabled = false;
|
|
|
|
MinorGridAxisY = false;
|
|
MarginAxisY = 7;
|
|
|
|
ShowLineAxisX = false;
|
|
ShowLineAxisY = true;
|
|
|
|
ShowLabelAxisX = true;
|
|
ShowLabelAxisY = true;
|
|
|
|
IntervalNumberAxisX = 4;
|
|
IntervalNumberAxisY = 4;
|
|
|
|
LabelFormatAxisY = FormatType.Intero;
|
|
LabelFormatAxisX = FormatType.Intero;
|
|
|
|
LegendWidthColumns = new List<int>() { 20, 15, 125 };
|
|
LegendSymbolHeight = 10;
|
|
LegendFontSizeText = 7;
|
|
|
|
BackImage = string.Empty;
|
|
|
|
IndicatorAxisX = null;
|
|
IndicatorAxisY = null;
|
|
|
|
CustomLabelAxisY = new List<CombinationPDFCustomLabel>();
|
|
CustomLabelAxisX = new List<CombinationPDFCustomLabel>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Costruttore
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
public CombinationPDF(float x)
|
|
: this()
|
|
{
|
|
X = x;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Costruttore
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="scale"></param>
|
|
public CombinationPDF(float x, float scale)
|
|
: this(x)
|
|
{
|
|
Scale = scale;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Costruttore
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="scale"></param>
|
|
/// <param name="y"></param>
|
|
public CombinationPDF(float x, float scale, float y)
|
|
: this(x, scale)
|
|
{
|
|
Y = y;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Metodi
|
|
|
|
/// <summary>
|
|
/// Cerca in tutti i Points aggiunti alla SeriesCollection e ne recupera il Values.Y massimo.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public double GetMaximumValueYPoints()
|
|
{
|
|
return SeriesCollection.SelectMany(a => a.Points, (a, b) => b.Values.Y).Max();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cerca in tutti i Points aggiunti alla SeriesCollection e ne recupera il Values.Y minimo.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public double GetMinimumValueYPoints()
|
|
{
|
|
return SeriesCollection.SelectMany(a => a.Points, (a, b) => b.Values.Y).Min();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cerca in tutti i Points aggiunti alla SeriesCollection e ne recupera il Values.X massimo.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public double GetMaximumValueXPoints()
|
|
{
|
|
return SeriesCollection.SelectMany(a => a.Points, (a, b) => b.Values.X).Max();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cerca in tutti i Points aggiunti alla SeriesCollection e ne recupera il Values.X minimo.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public double GetMinimunValueXPoints()
|
|
{
|
|
return SeriesCollection.SelectMany(a => a.Points, (a, b) => b.Values.X).Min();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converte in ObjectPDF l'oggetto PiePDF (ChartPDF).
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override PageElement ToElement()
|
|
{
|
|
var listReturn = new List<ObjectPDF>();
|
|
|
|
#region Creo il grafico
|
|
|
|
CreateChart();
|
|
#endregion
|
|
|
|
#region Ritorno l'immagine contenente il grafico
|
|
var image = ToImage();
|
|
listReturn.Add(image);
|
|
image.DeltaY = InnerChartDeltaY;
|
|
TotalHeight += Height;
|
|
|
|
#endregion
|
|
|
|
#region Ritorno la linea, le etichette e l'indicatore dell'Asse Y
|
|
|
|
listReturn.Add(new SpacePDF(Height + MarginAxisY));
|
|
TotalHeight += MarginAxisY;
|
|
|
|
#region Linea dell' asse Y
|
|
|
|
if (ShowLineAxisY)
|
|
listReturn.Add(new LinePDF(X, X) { DeltaY2ForVerticalLine = -(Height + MarginAxisY) });
|
|
|
|
#endregion
|
|
|
|
#region Etichette dell' asse Y
|
|
|
|
var counter = 0;
|
|
|
|
if (ShowLabelAxisY)
|
|
{
|
|
const float larghezzaMarcatoreAsseY = 5;
|
|
const float larghezzaEtichettaAsseY = 100F;
|
|
|
|
// Etichetta asse Y
|
|
var valoreEtichettaAsseY = _minimumAxisY;
|
|
|
|
if (LabelFormatAxisY != FormatType.Data && LabelFormatAxisY != FormatType.DataShort && !DontCalculateMaxAndMinAxisY)
|
|
valoreEtichettaAsseY = _minimumAxisY >= 0 ? 0 : _minimumAxisY;
|
|
|
|
#region Show Zero on Axis Y
|
|
if (showZeroInLabel)
|
|
{
|
|
List<double> valueList = new List<double>();
|
|
List<float> distanceList = new List<float>();
|
|
bool replacedValue = false;
|
|
bool showValue = true;
|
|
int index = -1;
|
|
|
|
// Get all the interval values
|
|
for (int i = 0; i <= IntervalNumberAxisY; i++)
|
|
valueList.Add((double)valoreEtichettaAsseY + (_intervalY*i));
|
|
|
|
var minAbsValue = valueList.Where(x => x != _minimumAxisY).Min();
|
|
if (Math.Abs(_minimumAxisY) > Math.Abs(minAbsValue) && Math.Min(Math.Abs(_minimumAxisY), Math.Abs(minAbsValue)) <= 2)
|
|
{
|
|
double toReplace = minAbsValue;
|
|
int indexToReplace = valueList.FindIndex(x => x == toReplace);
|
|
valueList[indexToReplace] = 0d;
|
|
replacedValue = true;
|
|
}
|
|
else
|
|
{
|
|
valueList.Add((double)0d);
|
|
valueList.Sort();
|
|
IntervalNumberAxisY++;
|
|
}
|
|
var spaceBetweenLabel = -(Height / (replacedValue ? IntervalNumberAxisY : IntervalNumberAxisY - 1));
|
|
|
|
for (int i = 0; i < valueList.Count() - 1; i++)
|
|
{
|
|
var toRound = spaceBetweenLabel * (valueList[i + 1] - valueList[i]) / _intervalY;
|
|
if (Math.Abs(toRound) < 6.0)
|
|
index = valueList[i] == 0 ? i + 1 : i;
|
|
distanceList.Add(Convert.ToSingle(toRound));
|
|
|
|
}
|
|
|
|
counter = 0;
|
|
do
|
|
{
|
|
showValue = counter != index ? true : false;
|
|
valoreEtichettaAsseY = valueList[counter];
|
|
|
|
#region Marcatore asse Y presente solo de ShowLineAxisY = true
|
|
|
|
if (ShowLineAxisY)
|
|
if (showValue)
|
|
{
|
|
listReturn.Add(new LinePDF(X, X - larghezzaMarcatoreAsseY, 0.5F) { AutoIncrementYWritable = false });
|
|
|
|
#endregion
|
|
|
|
#region Label
|
|
listReturn.Add(new FormattedTextAreaPDF(Helper.FormatPercentage(Convert.ToString(valoreEtichettaAsseY), 0), (X - larghezzaEtichettaAsseY - larghezzaMarcatoreAsseY - 2), larghezzaEtichettaAsseY)
|
|
{
|
|
TextHorizontalAlign = TextAlign.Right,
|
|
AutoIncrementYWritable = false,
|
|
FontSize = 7,
|
|
DeltaY = -(4) //(-4 derviva da: FontSize / 2)
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
#region Grid
|
|
//Creation of the grid with the chosen style
|
|
if (valueList[counter] != _minimumAxisY && showValue)
|
|
{
|
|
listReturn.Add(new LinePDF()
|
|
{
|
|
X1 = X,
|
|
X2 = X + Width,
|
|
Color = ColorPDF.ConsulenzaBase_Grigio_SfondoColonnaHeaderFooterTabella,
|
|
Width = 0.20F,
|
|
AutoIncrementYWritable = false,
|
|
BorderStyle = LineStyle.Dots
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
#region Space between labels
|
|
//Decreasing space for the next label
|
|
if (counter < IntervalNumberAxisY)
|
|
listReturn.Add(new SpacePDF(distanceList[counter]));
|
|
#endregion
|
|
|
|
counter++;
|
|
}
|
|
while (counter <= IntervalNumberAxisY);
|
|
}
|
|
#endregion
|
|
|
|
else
|
|
{
|
|
|
|
if (CalculateCustomIntegerLabelsAxisY)
|
|
{
|
|
int range = (int)_maximumAxisY - (int)_minimumAxisY;
|
|
int minValue = (int)_minimumAxisY;
|
|
int maxValue = (int)_maximumAxisY;
|
|
int offset = (int)(Math.Round((double)(range / 7)));
|
|
int counterIntervals = 0;
|
|
for (int i = minValue; i <= maxValue; i += offset)
|
|
{
|
|
CustomLabelAxisY.Add(new CombinationPDFCustomLabel() { Text = ((double)i).ToString("F"), Value = i });
|
|
counterIntervals++;
|
|
}
|
|
IntervalNumberAxisY = counterIntervals;
|
|
}
|
|
|
|
if (CustomLabelAxisY.Any())
|
|
{
|
|
#region Label personalizzate
|
|
counter = 0;
|
|
do
|
|
{
|
|
// Calcolo dello spazio in cui disegnare la custom label dall'inizio del grafico in funzione del valore della CustomLabelAxisY corrente.
|
|
float spazioCustomLabelYDaInizioGrafico = 0;
|
|
if (CustomLabelAxisY[counter].Value >= 0)
|
|
{
|
|
float tmpHeight = Height * (float)_maximumAxisY / ((float)_maximumAxisY - (float)_minimumAxisY);
|
|
spazioCustomLabelYDaInizioGrafico = tmpHeight - (tmpHeight / (float)(_maximumAxisY / CustomLabelAxisY[counter].Value));
|
|
}
|
|
else
|
|
{
|
|
float positiveHeight = Height * (float)_maximumAxisY / ((float)_maximumAxisY - (float)_minimumAxisY);
|
|
float negativeHeight = Height * (float)Math.Abs(_minimumAxisY) / ((float)_maximumAxisY - (float)_minimumAxisY);
|
|
spazioCustomLabelYDaInizioGrafico = positiveHeight + (negativeHeight / (float)(Math.Abs(_minimumAxisY) / Math.Abs(CustomLabelAxisY[counter].Value)));
|
|
}
|
|
|
|
listReturn.Add(new SpacePDF(-(Height - spazioCustomLabelYDaInizioGrafico)));
|
|
|
|
#region Marcatore asse Y presente solo de ShowLineAxisY = true
|
|
|
|
if (ShowLineAxisY)
|
|
listReturn.Add(new LinePDF(X, X - larghezzaMarcatoreAsseY, 0.5F) { AutoIncrementYWritable = false });
|
|
|
|
#endregion
|
|
|
|
// Etichetta asse Y
|
|
listReturn.Add(new FormattedTextAreaPDF(CustomLabelAxisY[counter].Text, X - larghezzaEtichettaAsseY - larghezzaMarcatoreAsseY - 2, larghezzaEtichettaAsseY)
|
|
{
|
|
TextHorizontalAlign = TextAlign.Right,
|
|
AutoIncrementYWritable = false,
|
|
FontSize = 7,
|
|
DeltaY = -(4) //(-4 derviva da: FontSize / 2)
|
|
});
|
|
|
|
counter++;
|
|
|
|
if (counter < IntervalNumberAxisY)
|
|
listReturn.Add(new SpacePDF(Height - spazioCustomLabelYDaInizioGrafico)); // Torno alla fine del grafico (origine)
|
|
else
|
|
listReturn.Add(new SpacePDF(-spazioCustomLabelYDaInizioGrafico)); // Mi posiziono all'inizio del grafico
|
|
}
|
|
while (counter < IntervalNumberAxisY);
|
|
#endregion
|
|
}
|
|
else
|
|
{
|
|
#region Label ad incremento standard
|
|
counter = 0;
|
|
do
|
|
{
|
|
#region Marcatore asse Y presente solo de ShowLineAxisY = true
|
|
|
|
if (ShowLineAxisY)
|
|
listReturn.Add(new LinePDF(X, X - larghezzaMarcatoreAsseY, 0.5F) { AutoIncrementYWritable = false });
|
|
|
|
#endregion
|
|
|
|
#region Testo etichetta asse Y
|
|
|
|
var sEtichettaAsseY = string.Empty; // Etichetta asse Y
|
|
switch (LabelFormatAxisY)
|
|
{
|
|
case FormatType.Intero:
|
|
sEtichettaAsseY = Helper.FormatInteger(Convert.ToString(valoreEtichettaAsseY));
|
|
break;
|
|
case FormatType.Decimale0:
|
|
sEtichettaAsseY = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseY), 0);
|
|
break;
|
|
case FormatType.Decimale1:
|
|
sEtichettaAsseY = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseY), 1);
|
|
break;
|
|
case FormatType.Decimale2:
|
|
sEtichettaAsseY = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseY), 2);
|
|
break;
|
|
case FormatType.Decimale2ConSeparatore:
|
|
sEtichettaAsseY = Helper.FormatCurrency(Convert.ToString(valoreEtichettaAsseY));
|
|
break;
|
|
case FormatType.Valuta:
|
|
sEtichettaAsseY = Helper.FormatCurrencyWithSymbol(Convert.ToString(valoreEtichettaAsseY));
|
|
break;
|
|
case FormatType.Percentuale:
|
|
sEtichettaAsseY = Helper.FormatPercentage(Convert.ToString(valoreEtichettaAsseY), 0);
|
|
break;
|
|
case FormatType.Data:
|
|
sEtichettaAsseY = DateTime.FromOADate(valoreEtichettaAsseY).ToString();
|
|
break;
|
|
case FormatType.DataShort:
|
|
sEtichettaAsseY = DateTime.FromOADate(valoreEtichettaAsseY).ToShortDateString();
|
|
break;
|
|
case FormatType.PercentualeImmobiliare:
|
|
sEtichettaAsseY = Helper.FormatPercentage(Convert.ToString(valoreEtichettaAsseY), 1);
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
listReturn.Add(new FormattedTextAreaPDF(sEtichettaAsseY, (X - larghezzaEtichettaAsseY - larghezzaMarcatoreAsseY - 2), larghezzaEtichettaAsseY)
|
|
{
|
|
TextHorizontalAlign = TextAlign.Right,
|
|
AutoIncrementYWritable = false,
|
|
FontSize = 7,
|
|
DeltaY = -(4) //(-4 derviva da: FontSize / 2)
|
|
});
|
|
|
|
// Incremento valoreEtichettaAsseY
|
|
valoreEtichettaAsseY += _intervalY;
|
|
|
|
//Decremento lo spazio su cui andrà a posizionarsi la prossima etichetta
|
|
if (counter < IntervalNumberAxisY)
|
|
listReturn.Add(new SpacePDF(-(Height / IntervalNumberAxisY)));
|
|
|
|
counter++;
|
|
}
|
|
while (counter <= IntervalNumberAxisY);
|
|
#endregion
|
|
}
|
|
}////////
|
|
|
|
}
|
|
#endregion
|
|
|
|
#region Indicatore dell' asse Y
|
|
|
|
if (IndicatorAxisY.HasValue)
|
|
{
|
|
const int altezzaRettangoloIndicatoreAsseY = 30;
|
|
const int larghezzaRettangoloIndicatoreAsseY = 70;
|
|
|
|
// Calcolo dello spazio in cui disegnare l'indicatore dall'inizio del grafico.
|
|
var spazioIndicatoreYDaInizioGrafico = Height - (Height / (float)(_maximumAxisY / IndicatorAxisY.Value.Value));
|
|
listReturn.Add(new SpacePDF(spazioIndicatoreYDaInizioGrafico));
|
|
|
|
//Rettangolo che forma la punta
|
|
listReturn.Add(new RectanglePDF(X + IndicatorAxisY.Value.DeltaX + larghezzaRettangoloIndicatoreAsseY, altezzaRettangoloIndicatoreAsseY / 1.414F, altezzaRettangoloIndicatoreAsseY / 1.414F, ColorPDF.Standard_Grigio_SfondoColonnaTabella) { AutoIncrementYWritable = false, DeltaY = -(altezzaRettangoloIndicatoreAsseY / 2), Angle = 45 });
|
|
|
|
//Rettangolo contenitore
|
|
listReturn.Add(new RectanglePDF(X + IndicatorAxisY.Value.DeltaX, altezzaRettangoloIndicatoreAsseY, larghezzaRettangoloIndicatoreAsseY, ColorPDF.Standard_Grigio_SfondoColonnaTabella) { AutoIncrementYWritable = false, DeltaY = -(altezzaRettangoloIndicatoreAsseY / 2) });
|
|
|
|
// Testo
|
|
listReturn.Add(new FormattedTextAreaPDF(IndicatorAxisY.Value.Text, X + IndicatorAxisY.Value.DeltaX + 2, larghezzaRettangoloIndicatoreAsseY) { FontBold = true, FontSize = 7, AutoIncrementYWritable = false, DeltaY = IndicatorAxisY.Value.DeltaYText });
|
|
|
|
// Reset spazio
|
|
listReturn.Add(new SpacePDF(-(spazioIndicatoreYDaInizioGrafico)));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Ritorno la linea e le etichette dall'Asse X
|
|
|
|
listReturn.Add(new SpacePDF(Height));
|
|
|
|
#region Linea dell' asse X
|
|
|
|
if (ShowLineAxisX)
|
|
listReturn.Add(new LinePDF(X, (X + Width)));
|
|
|
|
#endregion
|
|
|
|
#region Etichette dell' asse X
|
|
|
|
if (ShowLabelAxisX)
|
|
{
|
|
const float larghezzaMarcatoreAsseX = 5;
|
|
const float larghezzaEtichettaAsseX = 100F;
|
|
var xMarcatoreAsseX = X;
|
|
|
|
// Intervallo
|
|
var larghezzaIntervallo = Width / IntervalNumberAxisX;
|
|
|
|
// Etichetta asse X
|
|
var valoreEtichettaAsseX = _minimumAxisX;
|
|
|
|
if (LabelFormatAxisX != FormatType.Data && LabelFormatAxisX != FormatType.DataShort && LabelFormatAxisX != FormatType.DataSenzaOra)
|
|
valoreEtichettaAsseX = _minimumAxisX >= 0 ? 0 : _minimumAxisX;
|
|
|
|
if (CustomLabelAxisX.Any())
|
|
{
|
|
#region Label personalizzate
|
|
if (ShowCustomLabelsAxisX)
|
|
{
|
|
var minValueAxisX = ChartBase.ChartAreas[0].AxisX.Minimum;
|
|
var maxValueAxisX = ChartBase.ChartAreas[0].AxisX.Maximum;
|
|
var axisXValueWidth = maxValueAxisX - minValueAxisX;
|
|
foreach (var customLabel in CustomLabelAxisX)
|
|
{
|
|
var xLabelPosition = (1 - (maxValueAxisX - customLabel.Value) / axisXValueWidth) * ChartBaseWidth + X;
|
|
listReturn.Add(new LinePDF((float)xLabelPosition, (float)xLabelPosition, 0.5F) { DeltaY2ForVerticalLine = larghezzaMarcatoreAsseX });
|
|
|
|
var label = new FormattedTextAreaPDF(customLabel.Text, 0)
|
|
{
|
|
AutoIncrementYWritable = false,
|
|
DeltaY = larghezzaMarcatoreAsseX + 1
|
|
};
|
|
if (reportEnvironment == null)
|
|
{
|
|
throw new ApplicationException("Use SetReportEnvironment() method first, in order to use GetWidthReal method");
|
|
}
|
|
var labelWidth = label.GetWidthReal(reportEnvironment.FontFamily, false);
|
|
label.X = (float)xLabelPosition - labelWidth / 2;
|
|
listReturn.Add(label);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
counter = 0;
|
|
do
|
|
{
|
|
//Incremento X
|
|
xMarcatoreAsseX = X;
|
|
var incrementoAsseX = (Width / (float)_maximumAxisX) * (float)CustomLabelAxisX[counter].Value;
|
|
xMarcatoreAsseX += incrementoAsseX;
|
|
|
|
#region Marcatore asse X presente solo de ShowLineAxisX = true
|
|
|
|
if (ShowLineAxisX)
|
|
listReturn.Add(new LinePDF(xMarcatoreAsseX, xMarcatoreAsseX, 0.5F) { DeltaY2ForVerticalLine = larghezzaMarcatoreAsseX });
|
|
|
|
#endregion
|
|
|
|
counter++;
|
|
}
|
|
while (counter < IntervalNumberAxisX);
|
|
}
|
|
|
|
|
|
#endregion
|
|
}
|
|
else
|
|
{
|
|
#region Label ad incremento standard
|
|
counter = 0;
|
|
do
|
|
{
|
|
#region Marcatore asse X presente solo de ShowLineAxisX = true
|
|
|
|
if (ShowLineAxisX)
|
|
listReturn.Add(new LinePDF(xMarcatoreAsseX, xMarcatoreAsseX, 0.5F) { DeltaY2ForVerticalLine = larghezzaMarcatoreAsseX });
|
|
|
|
#endregion
|
|
|
|
#region Testo etichetta asse X
|
|
|
|
var sEtichettaAsseX = string.Empty; // Etichetta asse X
|
|
float centralabel = 0;
|
|
switch (LabelFormatAxisX)
|
|
{
|
|
case FormatType.Intero:
|
|
centralabel = xMarcatoreAsseX - 5;
|
|
sEtichettaAsseX = Helper.FormatInteger(Convert.ToString(valoreEtichettaAsseX));
|
|
break;
|
|
case FormatType.Decimale0:
|
|
centralabel = xMarcatoreAsseX - 5;
|
|
sEtichettaAsseX = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseX), 0);
|
|
break;
|
|
case FormatType.Decimale1:
|
|
centralabel = xMarcatoreAsseX - 5;
|
|
sEtichettaAsseX = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseX), 1);
|
|
break;
|
|
case FormatType.Decimale2:
|
|
centralabel = xMarcatoreAsseX - 8;
|
|
sEtichettaAsseX = Helper.FormatDecimal(Convert.ToString(valoreEtichettaAsseX), 2);
|
|
break;
|
|
case FormatType.Decimale2ConSeparatore:
|
|
centralabel = xMarcatoreAsseX - 8;
|
|
sEtichettaAsseX = Helper.FormatCurrency(Convert.ToString(valoreEtichettaAsseX));
|
|
break;
|
|
case FormatType.Valuta:
|
|
centralabel = xMarcatoreAsseX - 8;
|
|
sEtichettaAsseX = Helper.FormatCurrencyWithSymbol(Convert.ToString(valoreEtichettaAsseX));
|
|
break;
|
|
case FormatType.Percentuale:
|
|
centralabel = xMarcatoreAsseX - 8;
|
|
sEtichettaAsseX = Helper.FormatPercentage(Convert.ToString(valoreEtichettaAsseX), 0);
|
|
break;
|
|
case FormatType.PercentualeImmobiliare:
|
|
centralabel = xMarcatoreAsseX - 8;
|
|
sEtichettaAsseX = Helper.FormatPercentage(Convert.ToString(valoreEtichettaAsseX), 1);
|
|
break;
|
|
case FormatType.Data:
|
|
centralabel = xMarcatoreAsseX - 15;
|
|
sEtichettaAsseX = DateTime.FromOADate(valoreEtichettaAsseX).ToString();
|
|
break;
|
|
case FormatType.DataShort:
|
|
centralabel = xMarcatoreAsseX - 10;
|
|
sEtichettaAsseX = DateTime.FromOADate(valoreEtichettaAsseX).ToString("MM/yy");
|
|
break;
|
|
case FormatType.MeseAnno:
|
|
centralabel = xMarcatoreAsseX - 10;
|
|
sEtichettaAsseX = DateTime.FromOADate(valoreEtichettaAsseX).ToString("MMM-yy");
|
|
//sEtichettaAsseX = DateTime.ParseExact(valoreEtichettaAsseX.ToString(), "MMM-yy", new System.Globalization.CultureInfo("it-IT")).ToString();
|
|
break;
|
|
case FormatType.DataSenzaOra:
|
|
centralabel = xMarcatoreAsseX - 20;
|
|
sEtichettaAsseX = DateTime.FromOADate(valoreEtichettaAsseX).ToString("dd/MM/yyyy");
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
|
|
listReturn.Add(new FormattedTextAreaPDF(sEtichettaAsseX, centralabel, larghezzaIntervallo)
|
|
{
|
|
TextHorizontalAlign = TextAlign.Left,
|
|
AutoIncrementYWritable = false,
|
|
FontSize = 7,
|
|
DeltaY = larghezzaMarcatoreAsseX + 2
|
|
});
|
|
|
|
// Incremento valoreEtichettaAsseX
|
|
if (EqualDateLabelDistanceAxisX)
|
|
{
|
|
valoreEtichettaAsseX = DateTime.FromOADate(valoreEtichettaAsseX).AddMonths(_intervalMonths).ToOADate();
|
|
}
|
|
else
|
|
{
|
|
valoreEtichettaAsseX += _intervalX;
|
|
}
|
|
|
|
//Incremento X
|
|
xMarcatoreAsseX += larghezzaIntervallo;
|
|
|
|
counter++;
|
|
}
|
|
while (counter <= IntervalNumberAxisX);
|
|
#endregion
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Indicatore dell' asse X
|
|
|
|
if (IndicatorAxisX.HasValue)
|
|
{
|
|
const int altezzaRettangoloIndicatoreAsseX = 25;
|
|
const int larghezzaRettangoloIndicatoreAsseX = 50;
|
|
|
|
listReturn.Add(new SpacePDF(altezzaRettangoloIndicatoreAsseX * 1.414F));
|
|
|
|
//Incremento X
|
|
var xIndicatoreAsseX = ((Width / (float)_maximumAxisX) * (float)IndicatorAxisX.Value.Value) - larghezzaRettangoloIndicatoreAsseX / 2;
|
|
|
|
// Rettangolo punta
|
|
listReturn.Add(new RectanglePDF(X + xIndicatoreAsseX + IndicatorAxisX.Value.DeltaX + (larghezzaRettangoloIndicatoreAsseX / 2), (float)larghezzaRettangoloIndicatoreAsseX / 1.414F, larghezzaRettangoloIndicatoreAsseX / 1.414F, ColorPDF.Standard_Grigio_SfondoColonnaTabella) { Angle = 45F, DeltaY = -(altezzaRettangoloIndicatoreAsseX) });
|
|
|
|
//Rettangolo contenitore
|
|
listReturn.Add(new RectanglePDF(X + xIndicatoreAsseX + IndicatorAxisX.Value.DeltaX, altezzaRettangoloIndicatoreAsseX, larghezzaRettangoloIndicatoreAsseX, ColorPDF.Standard_Grigio_SfondoColonnaTabella) { AutoIncrementYWritable = false, DeltaY = -(altezzaRettangoloIndicatoreAsseX * 1.414F) });
|
|
|
|
// Testo
|
|
listReturn.Add(new FormattedTextAreaPDF(IndicatorAxisX.Value.Text, X + xIndicatoreAsseX + IndicatorAxisX.Value.DeltaX + 2, larghezzaRettangoloIndicatoreAsseX) { FontBold = true, FontSize = 7, DeltaY = -(altezzaRettangoloIndicatoreAsseX * 1.600F), DeltaX = IndicatorAxisX.Value.DeltaXText });
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
// custom markers
|
|
double maxAxisXVal = ChartBase.ChartAreas[0].AxisX.Maximum;
|
|
double minAxisXVal = ChartBase.ChartAreas[0].AxisX.Minimum;
|
|
double maxAxisYVal = ChartBase.ChartAreas[0].AxisY.Maximum;
|
|
double minAxisYVal = ChartBase.ChartAreas[0].AxisY.Minimum;
|
|
double axisXRange = maxAxisXVal - minAxisXVal;
|
|
double axisYRange = maxAxisYVal - minAxisYVal;
|
|
foreach (var item in SeriesCollection)
|
|
{
|
|
foreach (var point in item.Points)
|
|
{
|
|
if (point.Visible)
|
|
{
|
|
if (point.Marker != null)
|
|
{
|
|
int test = 2;
|
|
|
|
listReturn.Add(new CircleRealPDF(point.Marker.MarkerSize, new ColorPDF(point.Marker.MarkerColor.R, point.Marker.MarkerColor.G, point.Marker.MarkerColor.B))
|
|
{
|
|
AutoIncrementYWritable = false,
|
|
DeltaX = X + (float)(point.Values.X - minAxisXVal) / (float)axisXRange * image.Width,
|
|
DeltaY = Y - ((float)(point.Values.Y - minAxisYVal) / (float)axisYRange * image.Height)
|
|
});
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// end of drawing custom markers
|
|
|
|
#region Ritorno la Legenda
|
|
|
|
if (ShowLegend)
|
|
{
|
|
// Aggiungo lo spazio del MarginAxisY e dell'altezza della Linea, marcatore e del testo dell'asse Y
|
|
listReturn.Add(new SpacePDF(10));
|
|
|
|
var xLegenda = (X - 40) + LegendDeltaX;
|
|
var tabellaLegenda = new TablePDF(xLegenda, SeriesCollection.Count * 3, 1)
|
|
{
|
|
ID = "legend",
|
|
Footer = false,
|
|
Header = false,
|
|
PageBreak = false,
|
|
YOffset = _legendYOffset
|
|
}; // *3 pari al numero di colonne di cui si compone la legenda (immagine, spazio, testo)
|
|
|
|
var j = 0;
|
|
foreach (var serie in SeriesCollection)
|
|
{
|
|
if (serie.ShowInLegend)
|
|
{
|
|
tabellaLegenda.Columns.Add(new ColumnPDF("immagine" + j, LegendWidthColumns[0], HorizontalAlignmentType.Sinistra, false, false, LegendFontSizeText, ColumnType.Objectpdf));
|
|
tabellaLegenda.Columns.Add(new ColumnPDF("spazio" + j, LegendWidthColumns[1], HorizontalAlignmentType.Sinistra, false, false, LegendFontSizeText, ColumnType.Testo));
|
|
tabellaLegenda.Columns.Add(new ColumnPDF("testo" + j, LegendWidthColumns[2], HorizontalAlignmentType.Sinistra, false, false, LegendFontSizeText, ColumnType.Testo));
|
|
|
|
tabellaLegenda.Cells[j, 0].ValueObject = new RectanglePDF(LegendSymbolHeight, LegendWidthColumns[0], serie.Color) { AutoIncrementYWritable = false, DeltaY = LegendSymbolDeltaY };
|
|
tabellaLegenda.Cells[j + 1, 0].Value = string.Empty;
|
|
tabellaLegenda.Cells[j + 2, 0].Value = serie.Text;
|
|
|
|
j += 3;
|
|
}
|
|
}
|
|
|
|
listReturn.Add(tabellaLegenda);
|
|
|
|
TotalHeight += 10; // +10 = tabellaLegenda.Cells[j, 0].Height
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
Elements.AddRange(listReturn);
|
|
|
|
return this;
|
|
}
|
|
private int MonthDifference(DateTime lValue, DateTime rValue)
|
|
{
|
|
return Math.Abs((lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year));
|
|
}
|
|
/// <summary>
|
|
/// Crea il grafico di tipo StackedBar
|
|
/// </summary>
|
|
private void CreateChart()
|
|
{
|
|
var path = HttpContext.Current.Server.MapPath(".");
|
|
|
|
ChartBase.AntiAliasing = AntiAliasing.All;
|
|
ChartBase.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
|
|
|
|
// Disabilito il 3D
|
|
ChartBase.ChartAreas[0].Area3DStyle.Enable3D = false;
|
|
|
|
ChartBase.ChartAreas[0].BackColor = System.Drawing.Color.FromArgb(BackColor.Red, BackColor.Green, BackColor.Blue);
|
|
ChartBase.ChartAreas[0].BorderColor = System.Drawing.Color.Empty;
|
|
ChartBase.ChartAreas[0].BorderWidth = 0;
|
|
|
|
ChartBase.ChartAreas[0].Position.Auto = true;
|
|
ChartBase.ChartAreas[0].Position.X = 0;
|
|
ChartBase.ChartAreas[0].Position.Y = 0;
|
|
ChartBase.ChartAreas[0].Position.Width = 100;
|
|
ChartBase.ChartAreas[0].Position.Height = 100;
|
|
|
|
// Set the plotting area position. Coordinates of a plotting
|
|
// area are relative to a chart area position.
|
|
ChartBase.ChartAreas[0].InnerPlotPosition.Auto = true;
|
|
|
|
#region BackGroundImage
|
|
|
|
if (!string.IsNullOrEmpty(BackImage))
|
|
{
|
|
ChartBase.ChartAreas[0].BackImage = string.Format(@"{0}\Images\{1}", path, BackImage);
|
|
ChartBase.ChartAreas[0].BackImageMode = ChartImageWrapMode.Scaled;
|
|
|
|
}
|
|
#endregion
|
|
|
|
#region Impostazioni Asse X
|
|
|
|
switch (LabelFormatAxisX)
|
|
{
|
|
case FormatType.Data:
|
|
case FormatType.DataShort:
|
|
case FormatType.DataSenzaOra:
|
|
|
|
if (EqualDateLabelDistanceAxisX)
|
|
{
|
|
_minimumDate = DateTime.FromOADate(GetMinimunValueXPoints());
|
|
_maximumDate = DateTime.FromOADate(GetMaximumValueXPoints());
|
|
int monthsDifference = MonthDifference(_minimumDate, _maximumDate);
|
|
if (monthsDifference % IntervalNumberAxisX != 0)
|
|
{
|
|
_intervalMonths = (int)(monthsDifference / IntervalNumberAxisX) + 1;
|
|
monthsDifference = _intervalMonths * IntervalNumberAxisX;
|
|
_intervalDays = _intervalMonths * 30;
|
|
}
|
|
else
|
|
{
|
|
_intervalMonths = (int)(monthsDifference / IntervalNumberAxisX);
|
|
}
|
|
DateTime tmp = _minimumDate.AddMonths(monthsDifference);
|
|
_maximumDate = new DateTime(tmp.Year, tmp.Month, 1).AddMonths(1).AddSeconds(-1);
|
|
}
|
|
else
|
|
{
|
|
_minimumDate = DateTime.FromOADate(GetMinimunValueXPoints());
|
|
_maximumDate = DateTime.FromOADate(GetMaximumValueXPoints());
|
|
// calcolo la differenza in giorni tra minDate e maxDate
|
|
var days = _maximumDate.Subtract(_minimumDate).Days;
|
|
_intervalDays = days / IntervalNumberAxisX;
|
|
}
|
|
|
|
ChartBase.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Days;
|
|
ChartBase.ChartAreas[0].AxisX.Interval = _intervalDays;
|
|
|
|
_minimumAxisX = _minimumDate.ToOADate();
|
|
_maximumAxisX = _maximumDate.ToOADate();
|
|
|
|
ChartBase.ChartAreas[0].AxisX.Maximum = AxisXMaximum ?? _maximumAxisX;
|
|
ChartBase.ChartAreas[0].AxisX.Minimum = AxisXMinimum ?? _minimumAxisX;
|
|
//_intervalX = Helper.Round(_intervalDays); issue 3908
|
|
_intervalX = _intervalDays; // nei grafici con date sull'asse x è richiesto di non arrotondare per avere le date impostate ai valori min e max
|
|
// ChartBase.ChartAreas[0].AxisX.LabelsAutoFitStyle = LabelsAutoFitStyle.LabelsAngleStep30;
|
|
// ChartBase.ChartAreas[0].AxisX.LabelStyle.FontAngle = -45;
|
|
break;
|
|
default:
|
|
_maximumAxisX = MaximumValueAxisX != 0 ? MaximumValueAxisX : Helper.Round(GetMaximumValueXPoints());
|
|
|
|
_minimumAxisX = StartFromZeroAxisX ? 0 : Helper.Round(GetMinimunValueXPoints());
|
|
|
|
_intervalX = MaximumValueAxisX != 0 ? _maximumAxisX / IntervalNumberAxisX : Helper.Round(_maximumAxisX / IntervalNumberAxisX);
|
|
_maximumAxisX = _intervalX * IntervalNumberAxisX;
|
|
|
|
ChartBase.ChartAreas[0].AxisX.Maximum = _maximumAxisX;
|
|
ChartBase.ChartAreas[0].AxisX.Minimum = _minimumAxisX;
|
|
ChartBase.ChartAreas[0].AxisX.Interval = _intervalX;
|
|
break;
|
|
}
|
|
|
|
ChartBase.ChartAreas[0].AxisX.Margin = false;
|
|
ChartBase.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
|
|
ChartBase.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
|
|
ChartBase.ChartAreas[0].AxisX.MinorTickMark.Enabled = false;
|
|
ChartBase.ChartAreas[0].AxisX.MajorTickMark.Enabled = false;
|
|
ChartBase.ChartAreas[0].AxisX.LineStyle = ChartDashStyle.NotSet;
|
|
|
|
#endregion
|
|
|
|
#region Impostazioni Asse Y
|
|
|
|
if (DontCalculateMaxAndMinAxisY)
|
|
{
|
|
_maximumAxisY = MaximumValueAxisY;
|
|
_minimumAxisY = MinimumValueAxisY;
|
|
_intervalY = Math.Abs(MaximumValueAxisY - MinimumValueAxisY) / IntervalNumberAxisY;
|
|
}
|
|
else if(RemoveWhiteSpacesY)
|
|
{
|
|
//_maximumAxisY = Math.Truncate(GetMaximumValueYPoints() + 1);
|
|
//_minimumAxisY = StartFromZeroAxisY ? 0 : Helper.Round(GetMinimumValueYPoints()) > 0 ? 0 : Helper.Round(GetMinimumValueYPoints());
|
|
//_intervalY = _maximumAxisY / IntervalNumberAxisY;
|
|
double tmpMaxValueY = GetMaximumValueYPoints();
|
|
double tmpMinValueY = StartFromZeroAxisY ? 0 : GetMinimumValueYPoints();
|
|
if (tmpMaxValueY == 0 && tmpMinValueY == 0)
|
|
{
|
|
_maximumAxisY = 1;
|
|
_minimumAxisY = 0 + AxisYMinimumValueOffset;
|
|
_intervalY = (_maximumAxisY - _minimumAxisY) / IntervalNumberAxisY;
|
|
}
|
|
else
|
|
{
|
|
double tmpDifference = Math.Abs(tmpMaxValueY - tmpMinValueY);
|
|
double tmpMinDifference = Math.Truncate(2 * tmpDifference / 100);
|
|
|
|
double tmpRoundedMin = StartFromZeroAxisY ? 0 : Helper.Round(GetMinimumValueYPoints(), true);
|
|
double tmpRoundedMax = Math.Truncate(Helper.Round(GetMaximumValueYPoints(), true));
|
|
|
|
if (Math.Abs(Math.Abs(tmpRoundedMin) - Math.Abs(tmpMinValueY)) < tmpMinDifference)
|
|
{
|
|
if (tmpRoundedMin < 0)
|
|
{
|
|
tmpRoundedMin -= tmpMinDifference;
|
|
}
|
|
else
|
|
{
|
|
tmpRoundedMin += tmpMinDifference;
|
|
}
|
|
}
|
|
|
|
if (Math.Abs(Math.Abs(tmpRoundedMax) - Math.Abs(tmpMaxValueY)) < tmpMinDifference)
|
|
{
|
|
if (tmpRoundedMin < 0)
|
|
{
|
|
tmpRoundedMax -= tmpMinDifference;
|
|
}
|
|
else
|
|
{
|
|
tmpRoundedMax += tmpMinDifference;
|
|
}
|
|
}
|
|
_maximumAxisY = tmpRoundedMax;
|
|
_minimumAxisY = tmpRoundedMin + AxisYMinimumValueOffset;
|
|
_intervalY = (_maximumAxisY - _minimumAxisY) / IntervalNumberAxisY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_maximumAxisY = MaximumValueAxisY != 0 ? MaximumValueAxisY : Helper.Round(GetMaximumValueYPoints());
|
|
_minimumAxisY = StartFromZeroAxisY ? 0 : Helper.Round(GetMinimumValueYPoints()) > 0 ? 0 : Helper.Round(GetMinimumValueYPoints());
|
|
_minimumAxisY += AxisYMinimumValueOffset;
|
|
_intervalY = MaximumValueAxisY != 0 ? _maximumAxisY / IntervalNumberAxisY : Helper.Round((_maximumAxisY - _minimumAxisY) / IntervalNumberAxisY);
|
|
if (_intervalY == 0)
|
|
{
|
|
_intervalY++;
|
|
}
|
|
_maximumAxisY = _intervalY * IntervalNumberAxisY + (_minimumAxisY);
|
|
|
|
|
|
//if (_minimumAxisY == _maximumAxisY && _minimumAxisY < 0)
|
|
//{
|
|
// _maximumAxisY += 1;
|
|
// _intervalY = 1d / IntervalNumberAxisY;
|
|
//}
|
|
//else
|
|
//{
|
|
// _intervalY = MaximumValueAxisY != 0 ? _maximumAxisY / IntervalNumberAxisY : Helper.Round((_maximumAxisY - _minimumAxisY) / IntervalNumberAxisY);
|
|
// _maximumAxisY = _intervalY * IntervalNumberAxisY + (_minimumAxisY);
|
|
//}
|
|
}
|
|
|
|
ChartBase.ChartAreas[0].AxisY.Maximum = _maximumAxisY;
|
|
ChartBase.ChartAreas[0].AxisY.Minimum = _minimumAxisY;
|
|
ChartBase.ChartAreas[0].AxisY.Interval = _intervalY;
|
|
|
|
ChartBase.ChartAreas[0].AxisY.Margin = false;
|
|
ChartBase.ChartAreas[0].AxisY.LabelsAutoFit = true;
|
|
ChartBase.ChartAreas[0].AxisY.LabelStyle.Enabled = false;
|
|
|
|
ChartBase.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
|
|
ChartBase.ChartAreas[0].AxisY.MajorTickMark.Enabled = false;
|
|
|
|
ChartBase.ChartAreas[0].AxisY.LineStyle = ChartDashStyle.NotSet;
|
|
|
|
// MinorGrid
|
|
|
|
if (MinorGridAxisY && !showZeroInLabel)
|
|
{
|
|
ChartBase.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
|
|
ChartBase.ChartAreas[0].AxisY.MinorGrid.LineStyle = ChartDashStyle.Dot;
|
|
ChartBase.ChartAreas[0].AxisY.MinorGrid.Interval = ChartBase.ChartAreas[0].AxisY.Interval;
|
|
|
|
ChartBase.ChartAreas[0].AxisY.MinorGrid.LineColor = System.Drawing.Color.Gray;
|
|
}
|
|
#endregion
|
|
|
|
#region Impostazioni delle Serie
|
|
int a = 0;
|
|
foreach (var item in SeriesCollection)
|
|
{
|
|
// Imposto il nome della serie
|
|
ChartBase.Series.Add(item.Name);
|
|
|
|
// Imposto il tipo di grafico
|
|
ChartBase.Series[item.Name].Type = item.Type;
|
|
if (item.MarkerStyle != null)
|
|
{
|
|
ChartBase.Series[item.Name].MarkerStyle = item.MarkerStyle ?? MarkerStyle.Circle;
|
|
}
|
|
|
|
if (item.MarkerSize != null)
|
|
{
|
|
ChartBase.Series[item.Name].MarkerSize = item.MarkerSize ?? 5;
|
|
}
|
|
|
|
// Labelstyle
|
|
if (!string.IsNullOrEmpty(item.LabelStyle))
|
|
{
|
|
ChartBase.Series[item.Name]["LabelStyle"] = item.LabelStyle;
|
|
}
|
|
|
|
if (item.AutoCalculateLastPointLabelPosition)
|
|
{
|
|
ChartBase.Series[item.Name]["LabelStyle"] = CalculateLabelPositionForLastPoint(item);
|
|
}
|
|
|
|
#region Personalizzazioni per tipo di Serie
|
|
switch (item.Type)
|
|
{
|
|
case SeriesChartType.Point:
|
|
// ChartBase.Series[item.Name].MarkerSize = 20;
|
|
//ChartBase.Series[item.Name].MarkerStyle = MarkerStyle.Circle;
|
|
//ChartBase.Series[item.Name].CustomAttributes = "LabelStyle=TopLeft";
|
|
ChartBase.Series[item.Name].ShadowOffset = 1;
|
|
ChartBase.Series[item.Name].FontColor = System.Drawing.Color.Black;
|
|
ChartBase.Series[item.Name].Font = new System.Drawing.Font("verdanab", 6F);
|
|
|
|
|
|
break;
|
|
case SeriesChartType.Area:
|
|
ChartBase.Series[item.Name].Color = System.Drawing.Color.FromArgb(item.Color.Red, item.Color.Green, item.Color.Blue);
|
|
break;
|
|
}
|
|
|
|
//MarkerImage
|
|
if (!string.IsNullOrEmpty(item.MarkerImage))
|
|
{
|
|
ChartBase.Series[item.Name].MarkerImage = string.Format(@"{0}\Images\{1}", path, item.MarkerImage);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Imposto il tipo di valori su asse X in funzione di LabelFormatType
|
|
|
|
switch (LabelFormatAxisX)
|
|
{
|
|
case FormatType.Data:
|
|
case FormatType.DataShort:
|
|
case FormatType.DataSenzaOra:
|
|
ChartBase.Series[item.Name].XValueType = ChartValueTypes.Date;
|
|
break;
|
|
default:
|
|
ChartBase.Series[item.Name].XValueType = ChartValueTypes.Auto;
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
#region Imposto il tipo di valori su asse Y in funzione di LabelFormatType
|
|
|
|
switch (LabelFormatAxisY)
|
|
{
|
|
case FormatType.Data:
|
|
case FormatType.DataShort:
|
|
case FormatType.DataSenzaOra:
|
|
|
|
ChartBase.Series[item.Name].YValueType = ChartValueTypes.Date;
|
|
break;
|
|
default:
|
|
ChartBase.Series[item.Name].YValueType = ChartValueTypes.Auto;
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
//Imposto la larghezza delle barre di ciascuna Serie
|
|
ChartBase.Series[item.Name]["PointWidth"] = item.PointWidth;
|
|
|
|
#region Bordo
|
|
|
|
// Bordo
|
|
if (item.Border)
|
|
{
|
|
ChartBase.Series[item.Name].BorderStyle = ChartDashStyle.Solid;
|
|
ChartBase.Series[item.Name].ShadowOffset = 4;
|
|
}
|
|
|
|
// BorderWidth
|
|
ChartBase.Series[item.Name].BorderWidth = Convert.ToInt32(item.BorderWidth);
|
|
// BorderStyle
|
|
ChartBase.Series[item.Name].BorderStyle = item.BorderStyle;
|
|
#endregion
|
|
|
|
#region Aggiunta dei Points
|
|
|
|
int i = 0;
|
|
foreach (var point in item.Points)
|
|
{
|
|
if (point.Visible)
|
|
{
|
|
ChartBase.Series[item.Name].Points.AddXY(point.Values.X, point.Values.Y);
|
|
|
|
ChartBase.Series[item.Name].Points[i].Color = System.Drawing.Color.FromArgb(point.Color.Red, point.Color.Green, point.Color.Blue);
|
|
ChartBase.Series[item.Name].Points[i].Label = point.Label;
|
|
ChartBase.Series[item.Name].Points[i].Font = point.Font;
|
|
//if (point.Marker != null)
|
|
//{
|
|
// ChartBase.Series[item.Name].Points[i].MarkerStyle = point.Marker.MarkerStyle;
|
|
// ChartBase.Series[item.Name].Points[i].MarkerSize = (int)point.Marker.MarkerSize;
|
|
// ChartBase.Series[item.Name].Points[i].MarkerColor = point.Marker.MarkerColor;
|
|
//}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
a++;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
private string CalculateLabelPositionForLastPoint(Serie serie)
|
|
{
|
|
if (serie.Points.Count == 0)
|
|
{
|
|
return "Auto";
|
|
}
|
|
double horizontalDiffToUseOwnAlgorithm = 0.12; // worst scenario string takes 20%
|
|
double verticalDiffToUseOwnAlgorithm = 0.05;
|
|
|
|
// for some reason, RendererPDF reverses entire collection, so we have to do the same (locally only)
|
|
Point[] tmp = new Point[serie.Points.Count];
|
|
serie.Points.CopyTo(tmp);
|
|
List<Point> reversedPoints = tmp.ToList();
|
|
reversedPoints.Reverse();
|
|
|
|
double axisYMax = ChartBase.ChartAreas[0].AxisY.Maximum;
|
|
double axisYMin = ChartBase.ChartAreas[0].AxisY.Minimum;
|
|
double axisXMax = ChartBase.ChartAreas[0].AxisX.Maximum;
|
|
double axisXMin = ChartBase.ChartAreas[0].AxisX.Minimum;
|
|
|
|
double pointX = reversedPoints.Last().Values.X;
|
|
double pointY = reversedPoints.Last().Values.Y;
|
|
|
|
double xRange = axisXMax - axisXMin;
|
|
double yRange = axisYMax - axisYMin;
|
|
|
|
double distanceFromTop = axisYMax - pointY;
|
|
double distanceFromBot = Math.Abs(axisYMin - pointY);
|
|
double distanceFromLeft = Math.Abs(axisXMin - pointX);
|
|
double distanceFromRight = axisXMax - pointX;
|
|
|
|
double verticalDiffToUseAlgo = yRange * verticalDiffToUseOwnAlgorithm;
|
|
double horizontalDiffToUseAlgo = xRange * horizontalDiffToUseOwnAlgorithm;
|
|
|
|
bool tooCloseToTop = verticalDiffToUseAlgo > distanceFromTop;
|
|
bool tooCloseToBot = verticalDiffToUseAlgo > distanceFromBot;
|
|
bool tooCloseToLeft = horizontalDiffToUseAlgo > distanceFromLeft;
|
|
bool tooCloseToRight = horizontalDiffToUseAlgo > distanceFromRight;
|
|
|
|
// determining, what quater the point is in
|
|
bool isOnTheLeftSide = true;
|
|
bool isOnTheTopSide = false;
|
|
|
|
if (pointX > axisXMin + xRange / 2)
|
|
{
|
|
isOnTheLeftSide = false;
|
|
}
|
|
if (pointY > axisYMin + yRange / 2)
|
|
{
|
|
isOnTheTopSide = true;
|
|
}
|
|
|
|
if (tooCloseToTop ||
|
|
tooCloseToBot ||
|
|
tooCloseToLeft ||
|
|
tooCloseToRight)
|
|
{
|
|
if (tooCloseToTop)
|
|
{
|
|
if (tooCloseToRight)
|
|
{
|
|
return "BottomLeft";
|
|
}
|
|
else
|
|
{
|
|
return "BottomRight";
|
|
}
|
|
}
|
|
else if (tooCloseToBot)
|
|
{
|
|
if (tooCloseToRight)
|
|
{
|
|
return "TopLeft";
|
|
}
|
|
else
|
|
{
|
|
return "TopRight";
|
|
}
|
|
}
|
|
else if (tooCloseToLeft)
|
|
{
|
|
if (isOnTheTopSide)
|
|
{
|
|
return "BottomRight";
|
|
}
|
|
else
|
|
{
|
|
return "TopRight";
|
|
}
|
|
}
|
|
else if (tooCloseToRight)
|
|
{
|
|
if (isOnTheTopSide)
|
|
{
|
|
return "BottomLeft";
|
|
}
|
|
else
|
|
{
|
|
return "TopLeft";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return "Auto";
|
|
}
|
|
return "Auto";
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Struttura degli indicatori del grafico CombinationPDF. [Riquadro grigio con freccia].
|
|
/// </summary>
|
|
public struct CombinationPDFIndicator
|
|
{
|
|
public double Value { get; set; }
|
|
public string Text { get; set; }
|
|
public float DeltaX { get; set; }
|
|
public float DeltaY { get; set; }
|
|
public float DeltaYText { get; set; }
|
|
public float DeltaXText { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Struttura delle label personalizzate del grafico CombinationPDF.
|
|
/// </summary>
|
|
public struct CombinationPDFCustomLabel
|
|
{
|
|
public double Value { get; set; }
|
|
public string Text { get; set; }
|
|
}
|
|
}
|