private AxisXHeightInfo CalculateAxisXHeight(ChartCollection <AxisAbs> axisCollection) { double topAxisTotalHeight = ChartConstant.ZERO_D, bottomAxisTotalHeight = ChartConstant.ZERO_D; if (axisCollection != null && axisCollection.Count > ChartConstant.ZERO_I) { double axisHeight; foreach (var axis in axisCollection) { axis.Validate();//验证坐标轴有效性 if (axis.AxisType != AxisType.X) { continue; } axisHeight = axis.GetXAxisHeight(); if (axis.IsAxisXBottom()) { bottomAxisTotalHeight += axisHeight; } else { topAxisTotalHeight += axisHeight; } } } return(new AxisXHeightInfo(topAxisTotalHeight, bottomAxisTotalHeight)); }
/// <summary> /// 子类重写此函数时,必须设置Y轴宽度 /// </summary> /// <param name="axisCanvas">画布</param> /// <param name="seriesCollection">Series集合</param> /// <returns>Label的Y列表</returns> protected override List <double> PrimitiveDrawY(Canvas axisCanvas, ChartCollection <ISeries> seriesCollection) { this._labelTextSize = this.MeasureLabelTextSize(); axisCanvas.Width = base.CalculateAxisSize(this._labelTextSize.Width); this._axisData = this.CreateAxisData(seriesCollection); return(this.DrawY(axisCanvas)); }
private NumberAxisValueArea GetMinAndMaxValue(ChartCollection <ISeries> seriesCollection) { double min = double.NaN, max = double.NaN; if (seriesCollection == null || seriesCollection.Count == ChartConstant.ZERO_I) { return(new NumberAxisValueArea(min, max)); } double tmpMin, tmpMax; foreach (var series in seriesCollection) { if (series.AxisX != this && series.AxisY != this) { continue; } this.PrimitiveGetMinAndMaxValue(this, series.Values, out tmpMin, out tmpMax); if (double.IsNaN(min) || tmpMin - min < base._PRE) { min = tmpMin; } if (double.IsNaN(max) || tmpMax - max > base._PRE) { max = tmpMax; } } return(new NumberAxisValueArea(min, max)); }
private void SeriesChanged(ChartCollection <ISeries> oldChartSeries, ChartCollection <ISeries> newChartSeries) { if (oldChartSeries != null) { oldChartSeries.ChartCollectionChanged -= Series_ChartCollectionChanged; foreach (var series in oldChartSeries) { if (series == null) { continue; } series.PropertyChanged -= Series_PropertyChanged; series.ValuesCollectionChanged -= Series_ValuesCollectionChanged; } } if (newChartSeries != null) { newChartSeries.ChartCollectionChanged += Series_ChartCollectionChanged; foreach (var series in newChartSeries) { if (series == null) { continue; } series.PropertyChanged += Series_PropertyChanged; series.ValuesCollectionChanged += Series_ValuesCollectionChanged; } } }
/// <summary> /// 绘制Y轴 /// </summary> /// <param name="seriesCollection">Series集合</param> /// <param name="axisHeight">Y轴高度</param> /// <returns>Label的Y列表</returns> internal List <double> DrawY(ChartCollection <ISeries> seriesCollection, double axisHeight) { this._axisCanvas.Children.Clear(); this._axisSize = axisHeight; this._axisCanvas.Height = axisHeight; this._axisCanvas.Margin = new Thickness(ChartConstant.ZERO_D); this.AddAxisYTitle(); return(this.PrimitiveDrawY(this._axisCanvas, seriesCollection)); }
private AxisYWidthInfo DrawAxisYByAxisXHeightInfo(ChartCollection <AxisAbs> axisCollection, UIElementCollection children, ChartCollection <ISeries> seriesCollection, double yAxisHeight, double top) { if (!ChartHelper.DoubleHasValue(yAxisHeight) || yAxisHeight <= ChartConstant.ZERO_D) { return(new AxisYWidthInfo(ChartConstant.ZERO_D, ChartConstant.ZERO_D, null)); } double leftAxisTotalWidth = ChartConstant.ZERO_D, rightAxisTotalWidth = ChartConstant.ZERO_D; Dictionary <AxisAbs, List <double> > axisYLabelDic = null; if (axisCollection != null && axisCollection.Count > ChartConstant.ZERO_I) { FrameworkElement axisYControl; double axisLeft = ChartConstant.ZERO_D, axisRight = ChartConstant.ZERO_D; List <double> yList; foreach (var axis in axisCollection) { if (axis.AxisType != AxisType.Y) { continue; } yList = axis.DrawY(seriesCollection, yAxisHeight); if (axis.EnableBackgroundLabelLine && yList != null) { if (axisYLabelDic == null) { axisYLabelDic = new Dictionary <AxisAbs, List <double> >(); } axisYLabelDic.Add(axis, yList); } axisYControl = axis.AxisControl; axisYControl.VerticalAlignment = VerticalAlignment.Top; children.Add(axisYControl); if (axis.IsAxisYLeft()) { axisYControl.HorizontalAlignment = HorizontalAlignment.Left; axisYControl.Margin = new Thickness(axisLeft, top, ChartConstant.ZERO_D, ChartConstant.ZERO_D); leftAxisTotalWidth += axis.Width; axisLeft += axis.Width; } else { axisYControl.HorizontalAlignment = HorizontalAlignment.Right; axisYControl.Margin = new Thickness(ChartConstant.ZERO_D, top, axisRight, ChartConstant.ZERO_D); rightAxisTotalWidth += axis.Width; axisRight += axis.Width; } } } return(new AxisYWidthInfo(leftAxisTotalWidth, rightAxisTotalWidth, axisYLabelDic)); }
private void FreezeAllLayout(ChartCollection <AxisAbs> axisCollection, IChartLegend legend, Canvas chartCanvas, Grid chartGrid, ScrollViewer scrollViewer, Grid chartContentGrid, LegendAddResult legendAddResult, AxisXHeightInfo axisXHeightInfo, AxisYWidthInfo axisYWidthInfo) { //添加scrollViewer scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; scrollViewer.VerticalAlignment = System.Windows.VerticalAlignment.Top; scrollViewer.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; scrollViewer.Content = chartContentGrid; chartGrid.Children.Add(scrollViewer); //布局legend var chartGridRowColumnDefinition = new ChartGridRowColumnDefinition(legendAddResult.HasLegend, legend, chartGrid); if (legendAddResult.HasLegend) { this.SetRowColumn(chartGrid, legend.LegendControl, chartGridRowColumnDefinition.Legend); } this.SetRowColumn(chartGrid, scrollViewer, chartGridRowColumnDefinition.Chart); //布局内部 var chartGridRowColumnDefinition2 = new ChartGridRowColumnDefinition(false, null, chartContentGrid, axisYWidthInfo, axisXHeightInfo); if (axisCollection != null && axisCollection.Count > ChartConstant.ZERO_I) { RowColumnDefinitionItem rowColumnDefinition; foreach (var axis in axisCollection) { switch (axis.DockOrientation) { case ChartDockOrientation.Left: rowColumnDefinition = chartGridRowColumnDefinition2.LeftAxis; break; case ChartDockOrientation.Top: rowColumnDefinition = chartGridRowColumnDefinition2.TopAxis; break; case ChartDockOrientation.Right: rowColumnDefinition = chartGridRowColumnDefinition2.RightAxis; break; case ChartDockOrientation.Bottom: rowColumnDefinition = chartGridRowColumnDefinition2.BottomAxis; break; default: throw new NotImplementedException(axis.DockOrientation.ToString()); } this.SetRowColumn(chartContentGrid, axis.AxisControl, rowColumnDefinition); } } this.SetRowColumn(chartContentGrid, chartCanvas, chartGridRowColumnDefinition2.Chart); }
private Dictionary <AxisAbs, List <double> > DrawAxisX(ChartCollection <AxisAbs> axisCollection, ChartCollection <ISeries> seriesCollection, Grid chartGrid, double xAxisWidth, double left) { if (!ChartHelper.DoubleHasValue(xAxisWidth) || xAxisWidth <= ChartConstant.ZERO_D) { return(null); } Dictionary <AxisAbs, List <double> > axisXLabelDic = null; bool hasAxis = axisCollection != null && axisCollection.Count > ChartConstant.ZERO_I; if (hasAxis) { FrameworkElement axisXControl; double axisTop = ChartConstant.ZERO_D, axisBottom = ChartConstant.ZERO_D; List <double> xList; foreach (var axis in axisCollection) { if (axis.AxisType != AxisType.X) { continue; } xList = axis.DrawX(seriesCollection, xAxisWidth); if (axis.EnableBackgroundLabelLine && xList != null) { if (axisXLabelDic == null) { axisXLabelDic = new Dictionary <AxisAbs, List <double> >(); } axisXLabelDic.Add(axis, xList); } axisXControl = axis.AxisControl; axisXControl.HorizontalAlignment = HorizontalAlignment.Left; chartGrid.Children.Add(axisXControl); if (axis.IsAxisXBottom()) { axisXControl.VerticalAlignment = VerticalAlignment.Top; axisXControl.Margin = new Thickness(left, axisTop, ChartConstant.ZERO_D, ChartConstant.ZERO_D); axisTop += axis.Height; } else { axisXControl.VerticalAlignment = VerticalAlignment.Bottom; axisXControl.Margin = new Thickness(left, ChartConstant.ZERO_D, ChartConstant.ZERO_D, axisBottom); axisBottom += axis.Height; } } } return(axisXLabelDic); }
/// <summary> /// 绘制X轴 /// </summary> /// <param name="axisCanvas">画布</param> /// <param name="seriesCollection">Series集合</param> /// <returns>Label的X列表</returns> protected override List <double> PrimitiveDrawX(Canvas axisCanvas, ChartCollection <ISeries> seriesCollection) { this.CreateAxisData(seriesCollection); if (this._axisData.Count == 0) { this._seriesSizeDic = null; return(null); } this._seriesSizeDic = this.GetSeriesSizeDic(seriesCollection); return(this.DrawX(axisCanvas)); }
private void UpdateAll() { if (this.IgnoreUpdateChart()) { return; } AxisFreezeInfo axisFreezeInfo = this.GetAxisFreezeInfo(); ChartCollection <AxisAbs> axes = this.Axes; ChartCollection <ISeries> series = this.Series; IChartLegend legend = this.Legend; Grid chartGrid = this._chartGrid; Canvas chartCanvas = this._chartCanvas; Grid chartContentGrid = this._chartContentGrid; ScrollViewer scrollViewer = this._scrollViewer; this.Content = null; scrollViewer.Content = null; this._scrollViewer.Content = null; chartGrid.Children.Clear(); chartCanvas.Children.Clear(); chartCanvas.MouseWheel -= ChartCanvas_MouseWheel; chartCanvas.MouseLeftButtonDown -= ChartCanvas_MouseLeftButtonDown; chartCanvas.MouseMove -= ChartCanvas_MouseMove; chartGrid.RowDefinitions.Clear(); chartGrid.ColumnDefinitions.Clear(); chartContentGrid.Children.Clear(); chartContentGrid.RowDefinitions.Clear(); chartContentGrid.ColumnDefinitions.Clear(); switch (axisFreezeInfo.AxisFreezeType) { case AxisFreezeType.None: this.UpdateNoneFreeze(axisFreezeInfo, axes, series, legend, chartCanvas, chartGrid, scrollViewer); break; case AxisFreezeType.X: this.UpdateFreezeX(axisFreezeInfo, axes, series, legend, chartCanvas, chartGrid, scrollViewer, chartContentGrid); break; case AxisFreezeType.Y: this.UpdateFreezeY(axisFreezeInfo, axes, series, legend, chartCanvas, chartGrid, scrollViewer, chartContentGrid); break; case AxisFreezeType.All: this.UpdateFreezeAll(axisFreezeInfo, axes, series, legend, chartCanvas, chartGrid, scrollViewer, chartContentGrid); break; default: throw new NotImplementedException(axisFreezeInfo.AxisFreezeType.ToString()); } }
private void NoneFreezeLayout(ChartCollection <AxisAbs> axisCollection, IChartLegend legend, Canvas chartCanvas, Grid chartGrid, ScrollViewer scrollViewer, LegendAddResult legendAddResult, AxisXHeightInfo axisXHeightInfo, AxisYWidthInfo axisYWidthInfo) { var chartGridRowColumnDefinition = new ChartGridRowColumnDefinition(legendAddResult.HasLegend, legend, chartGrid, axisYWidthInfo, axisXHeightInfo); if (legendAddResult.HasLegend) { this.SetRowColumn(chartGrid, legend.LegendControl, chartGridRowColumnDefinition.Legend); } if (axisCollection != null && axisCollection.Count > ChartConstant.ZERO_I) { RowColumnDefinitionItem rowColumnDefinition; foreach (var axis in axisCollection) { switch (axis.DockOrientation) { case ChartDockOrientation.Left: rowColumnDefinition = chartGridRowColumnDefinition.LeftAxis; break; case ChartDockOrientation.Top: rowColumnDefinition = chartGridRowColumnDefinition.TopAxis; break; case ChartDockOrientation.Right: rowColumnDefinition = chartGridRowColumnDefinition.RightAxis; break; case ChartDockOrientation.Bottom: rowColumnDefinition = chartGridRowColumnDefinition.BottomAxis; break; default: throw new NotImplementedException(axis.DockOrientation.ToString()); } this.SetRowColumn(chartGrid, axis.AxisControl, rowColumnDefinition); } } this.SetRowColumn(chartGrid, scrollViewer, chartGridRowColumnDefinition.Chart); chartCanvas.MouseWheel += ChartCanvas_MouseWheel; chartCanvas.MouseLeftButtonDown += ChartCanvas_MouseLeftButtonDown; chartCanvas.MouseMove += ChartCanvas_MouseMove; }
private void AxesChanged(ChartCollection <AxisAbs> oldAxisCollection, ChartCollection <AxisAbs> newAxisCollection) { if (oldAxisCollection != null) { oldAxisCollection.ChartCollectionChanged -= AxisCollection_ChartCollectionChanged; foreach (var axis in oldAxisCollection) { axis.PropertyChanged -= Axis_PropertyChanged; } } if (newAxisCollection != null) { newAxisCollection.ChartCollectionChanged += AxisCollection_ChartCollectionChanged; foreach (var axis in newAxisCollection) { axis.PropertyChanged += Axis_PropertyChanged; } } }
private Dictionary <IColumnSeries, double> GetSeriesSizeDic(ChartCollection <ISeries> seriesCollection) { Dictionary <IColumnSeries, double> seriesSizeDic = new Dictionary <IColumnSeries, double>(); IColumnSeries columnSeries; Rectangle templateColumn; double seriesSize; foreach (var series in seriesCollection) { if (!(series is IColumnSeries) | series.AxisX != this && series.AxisY != this) { continue; } columnSeries = (IColumnSeries)series; if (seriesSizeDic.ContainsKey(columnSeries)) { continue; } columnSeries.Size = double.NaN; templateColumn = ChartHelper.CreateColumn(columnSeries); seriesSize = double.NaN; if (series.AxisX == this) { seriesSize = templateColumn.Width; } else if (series.AxisY == this) { seriesSize = templateColumn.Height; } seriesSizeDic.Add(columnSeries, seriesSize); } return(seriesSizeDic); }
private DateTimeAxisData CreateAxisData(ChartCollection <ISeries> seriesCollection) { if (this._minValue == null || this._maxValue == null) { DateTimeMinAndMaxValue result = this.GetMinAndMaxValue(seriesCollection); if (this._minValue != null) { result.MinTime = this._minValue.Value; } if (this._maxValue != null) { result.MaxTime = this._maxValue.Value; } this.CompleteAxisAreaValue(result); return(this.CreateDateTimeAxisData(result.MinTime, result.MaxTime)); } else { return(this.CreateDateTimeAxisData(this._minValue, this._maxValue)); } }
private NumberAxisData CreateAxisData(ChartCollection <ISeries> seriesCollection) { if (!ChartHelper.DoubleHasValue(this._minValue) || !ChartHelper.DoubleHasValue(this._maxValue)) { NumberAxisValueArea result = this.GetMinAndMaxValue(seriesCollection); if (ChartHelper.DoubleHasValue(this._minValue)) { result.Min = this._minValue; } if (ChartHelper.DoubleHasValue(this._maxValue)) { result.Max = this._maxValue; } this.ZoomAxisValueArea(result); this.CompleteAxisAreaValue(result); return(this.CreateNumberAxisData(result.Min, result.Max)); } else { return(this.CreateNumberAxisData(this._minValue, this._maxValue)); } }
/// <summary> /// 绘制X轴 /// </summary> /// <param name="axisCanvas">画布</param> /// <param name="seriesCollection">Series集合</param> /// <returns>Label的X列表</returns> protected override List <double> PrimitiveDrawX(Canvas axisCanvas, ChartCollection <ISeries> seriesCollection) { this._axisData = this.CreateAxisData(seriesCollection); return(this.DrawX(axisCanvas)); }
/// <summary> /// 缩放 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ChartCanvas_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) { if (e.Delta == 0) { return; } ChartCollection <AxisAbs> axes = this.Axes; if (axes == null) { return; } //缩放坐标 List <AxisAbs> zoomedAxisList = null; Canvas chartCanvas = this._chartCanvas; double zoomChangeSize, translate; if (e.Delta > 0) { //放大 foreach (var axis in axes) { if (!axis.AllowZoomTranslate) { continue; } if (axis.ZoomOut(chartCanvas, out zoomChangeSize)) { if (zoomedAxisList == null) { zoomedAxisList = new List <AxisAbs>(); } translate = (ChartConstant.ZERO_D - zoomChangeSize) / 2; zoomedAxisList.Add(axis); switch (axis.AxisType) { case AxisType.Y: axis.TranslateY(translate); break; case AxisType.X: axis.TranslateX(translate); break; default: throw new NotImplementedException(); } } } } else { //缩小 foreach (var axis in axes) { if (!axis.AllowZoomTranslate) { continue; } if (axis.ZoomIn(chartCanvas, out zoomChangeSize)) { if (zoomedAxisList == null) { zoomedAxisList = new List <AxisAbs>(); } translate = (ChartConstant.ZERO_D - zoomChangeSize) / 2; zoomedAxisList.Add(axis); switch (axis.AxisType) { case AxisType.Y: axis.TranslateY(translate); break; case AxisType.X: axis.TranslateX(translate); break; default: throw new NotImplementedException(); } } } } //更新series ChartCollection <ISeries> seriesCollection = this.Series; if (seriesCollection != null && zoomedAxisList != null) { foreach (var series in seriesCollection) { if (zoomedAxisList.Contains(series.AxisX) || zoomedAxisList.Contains(series.AxisY)) { series.Update(); } } } }
private DateTimeMinAndMaxValue GetMinAndMaxValue(ChartCollection <ISeries> seriesCollection) { if (seriesCollection == null || seriesCollection.Count == 0) { return(new DateTimeMinAndMaxValue(null, null)); } DateTime? min = null, max = null; IChartAxisValue chartAxisValue; object obj; DateTime? time; foreach (var series in seriesCollection) { if (series.AxisX != this && series.AxisY != this || series.Values == null || series.Values.Count == 0) { continue; } foreach (var value in series.Values) { chartAxisValue = value as IChartAxisValue; if (chartAxisValue == null) { continue; } switch (this.AxisType) { case AxisType.X: obj = chartAxisValue.GetXValue(); break; case AxisType.Y: obj = chartAxisValue.GetYValue(); break; default: throw new NotImplementedException(this.AxisType.ToString()); } time = ChartHelper.ConvertToDateTime(obj); if (time == null) { continue; } if (min == null || time.Value < min.Value) { min = time.Value; } if (max == null || time.Value > max.Value) { max = time.Value; } } } return(new DateTimeMinAndMaxValue(min, max)); }
/// <summary> /// 子类重写此函数时,必须设置Y轴宽度 /// </summary> /// <param name="axisCanvas">画布</param> /// <param name="seriesCollection">Series集合</param> /// <returns>Label的Y列表</returns> protected abstract List <double> PrimitiveDrawY(Canvas axisCanvas, ChartCollection <ISeries> seriesCollection);
private void UpdateNoneFreeze(AxisFreezeInfo axisFreezeInfo, ChartCollection <AxisAbs> axisCollection, ChartCollection <ISeries> seriesCollection, IChartLegend legend, Canvas chartCanvas, Grid chartGrid, ScrollViewer scrollViewer) { /************************************************************************************************************ * 步骤: * 1.添加legend,并计算出发四周所占高度或宽度 * 2.计算X轴总高度 * 3.根据X轴总高度计算图表区域高度高度(等于Y轴高度) * 4.根据Y轴高度绘制Y轴,并计算Y轴宽度 * 5.根据Y轴宽度计算X轴宽度并绘制X轴 * 6.绘制坐标背景标记线 * 7.布局UI * 8.绘各Series和填充legend ************************************************************************************************************/ //chartGrid.ShowGridLines = true; //chartCanvas.Background = ColorBrushHelper.GetNextColor(); this.Content = chartGrid; //第一步 添加legend,并计算出发四周所占高度或宽度 LegendAddResult legendAddResult = this.AddLegend(legend, chartGrid); //第二步 计算X轴总高度 AxisXHeightInfo axisXHeightInfo = this.CalculateAxisXHeight(axisCollection); //第三步 根据X轴总高度计算图表区域高度高度(等于Y轴高度) double yAxisHeight = axisFreezeInfo.Height - axisXHeightInfo.TopAxisTotalHeight - axisXHeightInfo.BottomAxisTotalHeight - legendAddResult.Top - legendAddResult.Bottom; if (yAxisHeight < ChartConstant.ZERO_D) { yAxisHeight = ChartConstant.ZERO_D; } //第四步 根据Y轴高度绘制Y轴,并计算Y轴宽度 AxisYWidthInfo axisYWidthInfo = this.DrawAxisYByAxisXHeightInfo(axisCollection, chartGrid.Children, seriesCollection, yAxisHeight, ChartConstant.ZERO_D); //第五步 根据Y轴宽度计算X轴宽度并绘制X轴 double xAxisWidth = axisFreezeInfo.Width - axisYWidthInfo.LeftAxisTotalWidth - axisYWidthInfo.RightAxisTotalWidth - legendAddResult.Left - legendAddResult.Right; if (xAxisWidth < ChartConstant.ZERO_D) { xAxisWidth = ChartConstant.ZERO_D; } Dictionary <AxisAbs, List <double> > axisXLabelDic = this.DrawAxisX(axisCollection, seriesCollection, chartGrid, xAxisWidth, ChartConstant.ZERO_D); chartCanvas.Width = xAxisWidth; chartCanvas.Height = yAxisHeight; scrollViewer.BorderThickness = new Thickness(ChartConstant.ZERO_D); scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden; scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden; scrollViewer.Background = Brushes.Transparent; scrollViewer.Content = chartCanvas; chartGrid.Children.Add(scrollViewer); //第六步 绘制坐标背景标记线 this.DrawAxisBackgroundLabelLine(chartCanvas, axisYWidthInfo.AxisYLabelDic, axisXLabelDic); //第七步 布局UI this.NoneFreezeLayout(axisCollection, legend, chartCanvas, chartGrid, scrollViewer, legendAddResult, axisXHeightInfo, axisYWidthInfo); //第八步 绘各Series和填充legend this.DrawSeries(chartGrid, chartCanvas, seriesCollection, legendAddResult, legend); }
/// <summary> /// 返回Column X:宽度或Y:高度 /// </summary> /// <param name="seriesCollection"></param> /// <returns></returns> private void CreateAxisData(ChartCollection <ISeries> seriesCollection) { this._axisData.Clear(); if (seriesCollection == null || seriesCollection.Count == 0) { return; } IChartAxisValue chartAxisValue; object axisValue; LabelSeriesItem labelAxisItem, labelAxisItemTmp; int preCount; foreach (var series in seriesCollection) { if (!(series is IColumnSeries) | series.AxisX != this && series.AxisY != this || series.Values == null || series.Values.Count == 0) { continue; } preCount = this._axisData.Count > 0 ? this._axisData.Values.ElementAt(0).Count : 0; foreach (var value in series.Values) { chartAxisValue = value as IChartAxisValue; if (value == null) { continue; } axisValue = null; if (series.AxisX == this) { axisValue = chartAxisValue.GetXValue(); } else if (series.AxisY == this) { axisValue = chartAxisValue.GetYValue(); } if (axisValue == null) { axisValue = this._nullLabelAxisItem; } if (!this._axisData.TryGetValue(axisValue, out labelAxisItem)) { labelAxisItem = new LabelSeriesItem((IColumnSeries)series); if (this._axisData.Count > 0) { //补齐没有的项 labelAxisItemTmp = this._axisData.Values.ElementAt(0); for (int i = 0; i < preCount; i++) { labelAxisItem.Add(null, double.NaN); } } this._axisData.Add(axisValue, labelAxisItem); } labelAxisItem.Add(value, double.NaN); } //补齐没有的项 foreach (var labelAxisItem2 in this._axisData.Values) { while (labelAxisItem2.Count <= preCount) { labelAxisItem2.Add(null, double.NaN); } } } }
private void UpdateFreezeX(AxisFreezeInfo axisFreezeInfo, ChartCollection <AxisAbs> axisCollection, ChartCollection <ISeries> seriesCollection, IChartLegend legend, Canvas chartCanvas, Grid chartGrid, ScrollViewer scrollViewer, Grid chartContentGrid) { /************************************************************************************************************ * 步骤: * 1.添加legend,并计算出发四周所占高度或宽度 * 2.计算X轴总高度 * 3.根据Y轴高度绘制Y轴,并计算Y轴宽度 * 4.根据Y轴宽度计算X轴宽度并绘制X轴 * 5.绘制坐标背景标记线 * 6.绘各Series * 7.绘各Series和填充legend ************************************************************************************************************/ this.Content = chartGrid; //第一步 添加legend,并计算出发四周所占高度或宽度 LegendAddResult legendAddResult = this.AddLegend(legend, chartGrid); //第二步 计算X轴总高度 AxisXHeightInfo axisXHeightInfo = this.CalculateAxisXHeight(axisCollection); double height = this.ActualHeight - axisXHeightInfo.TopAxisTotalHeight - axisXHeightInfo.BottomAxisTotalHeight - legendAddResult.Top - legendAddResult.Bottom; //第三步 根据Y轴高度绘制Y轴,并计算Y轴宽度 double yAxisHeight = axisFreezeInfo.Height; if (yAxisHeight < ChartConstant.ZERO_D) { yAxisHeight = ChartConstant.ZERO_D; } else if (yAxisHeight - height < ChartConstant.ZERO_D) { //真实高度大于最小值,取更大值 yAxisHeight = height; } AxisYWidthInfo axisYWidthInfo = this.DrawAxisYByAxisXHeightInfo(axisCollection, chartContentGrid.Children, seriesCollection, yAxisHeight, ChartConstant.ZERO_D); //第四步 根据Y轴宽度计算X轴宽度并绘制X轴 double xAxisWidth = axisFreezeInfo.Width - axisYWidthInfo.LeftAxisTotalWidth - axisYWidthInfo.RightAxisTotalWidth - legendAddResult.Left - legendAddResult.Right - this._scrollBarWidth; if (xAxisWidth < ChartConstant.ZERO_D) { xAxisWidth = ChartConstant.ZERO_D; } Dictionary <AxisAbs, List <double> > axisXLabelDic = this.DrawAxisX(axisCollection, seriesCollection, chartGrid, xAxisWidth, axisYWidthInfo.LeftAxisTotalWidth); chartCanvas.Width = xAxisWidth; chartCanvas.Height = yAxisHeight; chartContentGrid.Children.Add(chartCanvas); //第五步 绘制坐标背景标记线 this.DrawAxisBackgroundLabelLine(chartCanvas, axisYWidthInfo.AxisYLabelDic, axisXLabelDic); //第六步 布局UI this.FreezeXLayout(axisCollection, legend, chartCanvas, chartGrid, scrollViewer, chartContentGrid, legendAddResult, axisXHeightInfo, axisYWidthInfo); //第七步 绘各Series和填充legend this.DrawSeries(chartGrid, chartCanvas, seriesCollection, legendAddResult, legend); }
private void UpdateFreezeY(AxisFreezeInfo axisFreezeInfo, ChartCollection <AxisAbs> axisCollection, ChartCollection <ISeries> seriesCollection, IChartLegend legend, Canvas chartCanvas, Grid chartGrid, ScrollViewer scrollViewer, Grid chartContentGrid) { /************************************************************************************************************ * 步骤: * 1.添加legend,并计算出发四周所占高度或宽度 * 2.计算X轴总高度 * 3.根据X轴总高度计算图表区域高度高度(等于Y轴高度) * 4.根据Y轴高度绘制Y轴,并计算Y轴宽度 * 5.根据宽度绘制X轴 * 6.绘制坐标背景标记线 * 7.布局UI * 8.绘各Series和填充legend ************************************************************************************************************/ //chartGrid.ShowGridLines = true; //chartCanvas.Background = ColorBrushHelper.GetNextColor(); this.Content = chartGrid; //第一步 添加legend,并计算出发四周所占高度或宽度 LegendAddResult legendAddResult = this.AddLegend(legend, chartGrid); //第二步 计算X轴总高度 AxisXHeightInfo axisXHeightInfo = this.CalculateAxisXHeight(axisCollection); //第三步 根据X轴总高度计算图表区域高度高度(等于Y轴高度) double yAxisHeight = axisFreezeInfo.Height - axisXHeightInfo.TopAxisTotalHeight - axisXHeightInfo.BottomAxisTotalHeight - legendAddResult.Top - legendAddResult.Bottom - this._scrollBarWidth; if (yAxisHeight < ChartConstant.ZERO_D) { yAxisHeight = ChartConstant.ZERO_D; } //第四步 根据Y轴高度绘制Y轴,并计算Y轴宽度 AxisYWidthInfo axisYWidthInfo = this.DrawAxisYByAxisXHeightInfo(axisCollection, chartGrid.Children, seriesCollection, yAxisHeight, axisXHeightInfo.TopAxisTotalHeight); //第五步 根据宽度绘制X轴 double width = this.ActualWidth - axisYWidthInfo.LeftAxisTotalWidth - axisYWidthInfo.RightAxisTotalWidth - legendAddResult.Left - legendAddResult.Right; double xAxisWidth = axisFreezeInfo.Width; if (xAxisWidth < ChartConstant.ZERO_D) { xAxisWidth = ChartConstant.ZERO_D; } else if (xAxisWidth - width < ChartConstant.ZERO_D) { //真实宽度大于最小值,取更大值 xAxisWidth = width; } Dictionary <AxisAbs, List <double> > axisXLabelDic = this.DrawAxisX(axisCollection, seriesCollection, chartContentGrid, xAxisWidth, ChartConstant.ZERO_D); chartCanvas.Width = xAxisWidth; chartCanvas.Height = yAxisHeight; chartContentGrid.Children.Add(chartCanvas); //第六步 绘制坐标背景标记线 this.DrawAxisBackgroundLabelLine(chartCanvas, axisYWidthInfo.AxisYLabelDic, axisXLabelDic); //第七步 布局UI this.FreezeYLayout(axisCollection, legend, chartCanvas, chartGrid, scrollViewer, chartContentGrid, legendAddResult, axisXHeightInfo, axisYWidthInfo); //第八步 绘各Series和填充legend this.DrawSeries(chartGrid, chartCanvas, seriesCollection, legendAddResult, legend); }
private void ChartCanvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) { if (e.LeftButton != MouseButtonState.Pressed) { return; } ChartCollection <AxisAbs> axes = this.Axes; if (axes == null || axes.Count == 0) { return; } var endPoint = e.MouseDevice.GetPosition(this._chartCanvas); double left = endPoint.X - this._beginPoint.X; double top = endPoint.Y - this._beginPoint.Y; if (left == ChartConstant.ZERO_D && top == ChartConstant.ZERO_D) { return; } this._beginPoint = endPoint; //平移坐标 Canvas chartCanvas = this._chartCanvas; List <AxisAbs> zoomedAxisList = null; bool translateResult; foreach (var axis in axes) { if (!axis.AllowZoomTranslate) { continue; } switch (axis.AxisType) { case AxisType.X: translateResult = axis.TranslateX(left); break; case AxisType.Y: translateResult = axis.TranslateY(top); break; default: throw new NotImplementedException(); } if (translateResult) { if (zoomedAxisList == null) { zoomedAxisList = new List <AxisAbs>(); } zoomedAxisList.Add(axis); } } //更新series ChartCollection <ISeries> seriesCollection = this.Series; if (seriesCollection != null && zoomedAxisList != null) { foreach (var series in seriesCollection) { if (zoomedAxisList.Contains(series.AxisX) || zoomedAxisList.Contains(series.AxisY)) { series.Update(); } } } }