本帖最后由 Richard.Ma 于 2024-1-22 12:10 编辑
在通过GCExcel代码自动化构建可视化图表的过程中,一些用户需要复制图表系列的配置,包括样式。以及系列中包含的元素及样式,如:数据标签,趋势线,误差线 等等。
本教程提供了代码复制同一个Chart的一个系列的样式及元素到另一个系列,以提供相同的展示效果。同时,大家也通过代码可以更好的理解系列中的样式和元素的结构。
首先,需要明确以下的前提条件
1.不是所有的内容都是可以复制的,不同系列一些属性肯定是不同的,否则图表会出错或者不同系列本身也就没有意义了。例如:系列名称,系列的引用数据区域等等
2.不是所有的Chart类型都有多个系列的,例如饼图,散点图,股票图,瀑布图等图表类型,都是用来展示单个系列的。
3.一个图表内的多个系列如果是不同的Chart类型,例如一个是柱形图,一个是点线图。那么相关的样式选项是不同的。因此复制时,应该先同步系列的类型。
4.对于填充,边框等等的样式,除了给series本身设置外,还需要注意给系列中的每个数据点设置。
具体的代码可以参考文末,提供了一个CloneSeries的静态方法。可以复制系列
需要调用的时候,可以通过这句代码
- ChartHelper.CloneSeries(chart.SeriesCollection[1], chart.SeriesCollection[0]);
复制代码
具体效果:
复制配置前
复制配置后
以下代码为C#代码,适用于GCExcel.NET组件,GCExcel Java版本和.NET版本的接口命名规则很类似。如有需要可以参考编写对应代码。
CloneSeries方法↓↓↓↓↓
- public static class ChartHelper
- {
- public static void CloneSeries(ISeries newSer, ISeries oldSer)
- {
- newSer.ChartType = oldSer.ChartType;
- //判断图表类型,当前仅测试了柱状图,折线图,面积图,条形图
- if (newSer.ChartType != ChartType.ColumnClustered &&
- newSer.ChartType != ChartType.Line &&
- newSer.ChartType != ChartType.LineMarkers &&
- newSer.ChartType != ChartType.Area &&
- newSer.ChartType != ChartType.BarClustered
- )
- {
- Exception ex = new Exception("Clone Series operation is not supported for this chart type");
- throw ex;
- }
-
- newSer.AxisGroup = oldSer.AxisGroup;
- newSer.PictureType = oldSer.PictureType;
- newSer.Smooth = oldSer.Smooth;
- //Format
- CloneFill(newSer.Format.Fill, oldSer.Format.Fill);
- CloneLine(newSer.Format.Line, oldSer.Format.Line);
- Clone3D(newSer.Format.ThreeD, oldSer.Format.ThreeD);//阴影/发光/柔化/3D等可以自己再设置
- newSer.InvertIfNegative = oldSer.InvertIfNegative;
- if (newSer.InvertIfNegative)
- {
- CloneColor(newSer.InvertColor, oldSer.InvertColor);
- }
-
- //Points Format
- for (int i = 0; i < Math.Min(newSer.Points.Count, oldSer.Points.Count); i++)
- {
- CloneFill(newSer.Points[i].Format.Fill, oldSer.Points[i].Format.Fill);
- CloneLine(newSer.Points[i].Format.Line, oldSer.Points[i].Format.Line);
- }
- //MarkerFormat for LineMarkers
- if (newSer.ChartType == ChartType.LineMarkers)
- {
- newSer.ShowMeanMarkers = oldSer.ShowMeanMarkers;
- newSer.MarkerSize = oldSer.MarkerSize;
- newSer.MarkerStyle = oldSer.MarkerStyle;
- CloneFill(newSer.MarkerFormat.Fill, oldSer.MarkerFormat.Fill);
- CloneLine(newSer.MarkerFormat.Line, oldSer.MarkerFormat.Line);
- for (int i = 0; i < Math.Min(newSer.Points.Count, oldSer.Points.Count); i++)
- {
- CloneFill(newSer.Points[i].MarkerFormat.Fill, oldSer.Points[i].MarkerFormat.Fill);
- CloneLine(newSer.Points[i].MarkerFormat.Line, oldSer.Points[i].MarkerFormat.Line);
- }
- }
- //Series DataLabels
- newSer.HasDataLabels = oldSer.HasDataLabels;
- if (newSer.HasDataLabels)
- {
- CloneFill(newSer.DataLabels.Format.Fill, oldSer.DataLabels.Format.Fill);
- CloneLine(newSer.DataLabels.Format.Line, oldSer.DataLabels.Format.Line);
- CloneFont(newSer.DataLabels.Font, oldSer.DataLabels.Font);
- CloneLabelOptions(newSer.DataLabels, oldSer.DataLabels, newSer.ChartType);
- //Point DataLabels
- for (int i = 0; i < Math.Min(newSer.DataLabels.Count, oldSer.DataLabels.Count); i++)
- {
- CloneFill(newSer.DataLabels[i].Format.Fill, oldSer.DataLabels[i].Format.Fill);
- CloneLine(newSer.DataLabels[i].Format.Line, oldSer.DataLabels[i].Format.Line);
- CloneFont(newSer.DataLabels[i].Font, oldSer.DataLabels[i].Font);
- }
- }
- //Trendlines
- newSer.Trendlines.All((tl) => { tl.Delete(); return true; });
- oldSer.Trendlines.All((tl) => { newSer.Trendlines.Add(); return true; });
- for (int i = 0; i < Math.Min(newSer.Trendlines.Count, oldSer.Trendlines.Count); i++)
- {
- CloneLine(newSer.Trendlines[i].Format.Line, oldSer.Trendlines[i].Format.Line);
- newSer.Trendlines[i].Type = oldSer.Trendlines[i].Type;
- if (newSer.Trendlines[i].Type == TrendlineType.MovingAvg)
- newSer.Trendlines[i].Period = oldSer.Trendlines[i].Period;
- if (newSer.Trendlines[i].Type == TrendlineType.Polynomial)
- newSer.Trendlines[i].Order = oldSer.Trendlines[i].Order;
- newSer.Trendlines[i].Backward = oldSer.Trendlines[i].Backward;
- newSer.Trendlines[i].Forward = oldSer.Trendlines[i].Forward;
- newSer.Trendlines[i].Intercept = oldSer.Trendlines[i].Intercept;
- newSer.Trendlines[i].DisplayEquation = oldSer.Trendlines[i].DisplayEquation;
- newSer.Trendlines[i].DisplayRSquared = oldSer.Trendlines[i].DisplayRSquared;
- }
- //ErrorBar
- if (oldSer.HasErrorBars)
- {
- newSer.HasErrorBars = oldSer.HasErrorBars;
- CloneErrorBar(newSer.YErrorBar, oldSer.YErrorBar);
- }
- }
- private static void CloneFill(IFillFormat newFill, IFillFormat oldFill)
- {
- switch (oldFill.Type)
- {
- case FillType.Solid:
- newFill.Color.ColorType = oldFill.Color.ColorType;
- switch (newFill.Color.ColorType)
- {
- case SolidColorType.RGB:
- newFill.Color.RGB = oldFill.Color.RGB;
- break;
- case SolidColorType.Theme:
- newFill.Color.ObjectThemeColor = oldFill.Color.ObjectThemeColor;
- newFill.Color.TintAndShade = oldFill.Color.TintAndShade;
- break;
- }
- newFill.Color.Brightness = oldFill.Color.Brightness;
- newFill.Transparency = oldFill.Transparency;
- newFill.Solid();
- break;
- case FillType.Gradient:
- newFill.PresetGradient(oldFill.GradientStyle, oldFill.GradientVariant, oldFill.PresetGradientType);
- foreach (IGradientStop item in oldFill.GradientStops)
- {
- newFill.GradientStops.Insert(item.Color.RGB.ToArgb(), item.Position, item.Transparency);
- }
- newFill.GradientPathType = oldFill.GradientPathType;
- newFill.GradientAngle = oldFill.GradientAngle;
- break;
- case FillType.Picture:
- //newFill.UserPicture(""); //不提供获取接口
- newFill.PatternColor.RGB = oldFill.PatternColor.RGB;
- newFill.PatternColor.ObjectThemeColor = oldFill.PatternColor.ObjectThemeColor;
- newFill.PatternColor.ColorType = oldFill.PatternColor.ColorType;
- newFill.PatternColor.TintAndShade = oldFill.PatternColor.TintAndShade;
- newFill.PatternColor.Brightness = oldFill.PatternColor.Brightness;
- newFill.Transparency = oldFill.Transparency;
- break;
- case FillType.Textured:
- newFill.PresetTextured(oldFill.PresetTexture);
- newFill.TextureAlignment = oldFill.TextureAlignment;
- newFill.TextureOffsetX = oldFill.TextureOffsetX;
- newFill.TextureOffsetY = oldFill.TextureOffsetY;
- break;
- case FillType.Patterned:
- newFill.Patterned(oldFill.Pattern);
- newFill.PatternColor.ColorType = oldFill.PatternColor.ColorType;
- switch (newFill.PatternColor.ColorType)
- {
- case SolidColorType.RGB:
- newFill.Color.RGB = oldFill.Color.RGB;
- newFill.PatternColor.RGB = oldFill.PatternColor.RGB;
- break;
- case SolidColorType.Theme:
- newFill.Color.ObjectThemeColor = oldFill.Color.ObjectThemeColor;
- newFill.Color.TintAndShade = oldFill.Color.TintAndShade;
- newFill.PatternColor.ObjectThemeColor = oldFill.PatternColor.ObjectThemeColor;
- newFill.PatternColor.TintAndShade = oldFill.PatternColor.TintAndShade;
- break;
- }
- newFill.PatternColor.Brightness = oldFill.PatternColor.Brightness;
- newFill.Transparency = oldFill.Transparency;
- break;
- }
- newFill.Visible = oldFill.Visible;
- }
- private static void CloneLine(ILineFormat newLine, ILineFormat oldLine)
- {
- newLine.Style = oldLine.Style;
- newLine.Weight = oldLine.Weight;
- newLine.DashStyle = oldLine.DashStyle;
- newLine.Transparency = oldLine.Transparency;
- switch (oldLine.Type)
- {
- case FillType.Solid:
- newLine.Solid();
- CloneColor(newLine.Color, oldLine.Color);
- break;
- case FillType.Gradient:
- newLine.PresetGradient(oldLine.GradientStyle, oldLine.GradientVariant, PresetGradientType.Ocean);
- foreach (IGradientStop item in oldLine.GradientStops)
- newLine.GradientStops.Insert(item.Color.RGB.ToArgb(), item.Position, item.Transparency);
- newLine.GradientAngle = oldLine.GradientAngle;
- break;
- }
- newLine.Visible = oldLine.Visible;
- }
- private static void CloneColor(IColorFormat newColor, IColorFormat oldColor)
- {
- newColor.ColorType = oldColor.ColorType;
- switch (newColor.ColorType)
- {
- case SolidColorType.RGB:
- newColor.RGB = oldColor.RGB;
- break;
- case SolidColorType.Theme:
- newColor.ObjectThemeColor = oldColor.ObjectThemeColor;
- newColor.TintAndShade = oldColor.TintAndShade;
- break;
- }
- newColor.Brightness = oldColor.Brightness;
- }
- private static void CloneFont(IFontFormat newFont, IFontFormat oldFont)
- {
- newFont.Color.ColorType = oldFont.Color.ColorType;
- switch (newFont.Color.ColorType)
- {
- case SolidColorType.RGB:
- newFont.Color.RGB = oldFont.Color.RGB;
- break;
- case SolidColorType.Theme:
- newFont.Color.ObjectThemeColor = oldFont.Color.ObjectThemeColor;
- newFont.Color.TintAndShade = oldFont.Color.TintAndShade;
- break;
- }
- newFont.Bold = oldFont.Bold;
- newFont.Italic = oldFont.Italic;
- newFont.Color.Brightness = oldFont.Color.Brightness;
- newFont.Size = oldFont.Size;
- newFont.Name = oldFont.Name;
- newFont.Underline = oldFont.Underline;
- newFont.Strikethrough = oldFont.Strikethrough;
- newFont.Superscript = oldFont.Superscript;
- newFont.Subscript = oldFont.Subscript;
- newFont.Italic = oldFont.Italic;
- }
- private static void CloneLabelOptions(IDataLabels newLabels, IDataLabels oldLabels, ChartType chartType)
- {
- newLabels.ShowValue = oldLabels.ShowValue;
- newLabels.ShowCategoryName = oldLabels.ShowCategoryName;
- newLabels.ShowSeriesName = oldLabels.ShowSeriesName;
- newLabels.ShowLegendKey = oldLabels.ShowLegendKey;
- newLabels.ShowLeaderLines = oldLabels.ShowLeaderLines;
- newLabels.Separator = oldLabels.Separator;
- newLabels.Position = oldLabels.Position;
- newLabels.NumberFormat = oldLabels.NumberFormat;
- if (chartType == ChartType.Pie || chartType == ChartType.Doughnut)
- newLabels.ShowPercentage = oldLabels.ShowPercentage;
- if (chartType == ChartType.Bubble)
- newLabels.ShowBubbleSize = oldLabels.ShowBubbleSize;
- for (int i = 0; i < Math.Min(newLabels.Count, oldLabels.Count); i++)
- {
- newLabels[i].Position = oldLabels[i].Position;
- newLabels[i].ShowValue = oldLabels[i].ShowValue;
- newLabels[i].ShowCategoryName = oldLabels[i].ShowCategoryName;
- newLabels[i].ShowSeriesName = oldLabels[i].ShowSeriesName;
- newLabels[i].ShowLegendKey = oldLabels[i].ShowLegendKey;
- newLabels[i].Separator = oldLabels[i].Separator;
- newLabels[i].Position = oldLabels[i].Position;
- newLabels[i].Text = oldLabels[i].Text;
- newLabels[i].NumberFormat = oldLabels[i].NumberFormat;
- if (chartType == ChartType.Pie || chartType == ChartType.Doughnut)
- newLabels[i].ShowPercentage = oldLabels[i].ShowPercentage;
- if (chartType == ChartType.Bubble)
- newLabels[i].ShowBubbleSize = oldLabels[i].ShowBubbleSize;
- }
- }
- private static void CloneErrorBar(IErrorBar newErr, IErrorBar oldErr)
- {
- newErr.Type = oldErr.Type;
- newErr.Amount = oldErr.Amount;
- newErr.EndStyle = oldErr.EndStyle;
- newErr.ValueType = oldErr.ValueType;
- switch (newErr.ValueType)
- {
- case ErrorBarType.Custom:
- newErr.Minus = oldErr.Minus;
- newErr.Plus = oldErr.Plus;
- break;
- }
- CloneLine(newErr.Format.Line, oldErr.Format.Line);
- }
- private static void Clone3D(IThreeDFormat newo3d, IThreeDFormat old3d)
- {
- }
- }
复制代码
|
|