GCExcel复制Chart中一个系列的配置到另一个系列
本帖最后由 Richard.Ma 于 2024-1-22 12:10 编辑在通过GCExcel代码自动化构建可视化图表的过程中,一些用户需要复制图表系列的配置,包括样式。以及系列中包含的元素及样式,如:数据标签,趋势线,误差线 等等。
本教程提供了代码复制同一个Chart的一个系列的样式及元素到另一个系列,以提供相同的展示效果。同时,大家也通过代码可以更好的理解系列中的样式和元素的结构。
首先,需要明确以下的前提条件
1.不是所有的内容都是可以复制的,不同系列一些属性肯定是不同的,否则图表会出错或者不同系列本身也就没有意义了。例如:系列名称,系列的引用数据区域等等
2.不是所有的Chart类型都有多个系列的,例如饼图,散点图,股票图,瀑布图等图表类型,都是用来展示单个系列的。
3.一个图表内的多个系列如果是不同的Chart类型,例如一个是柱形图,一个是点线图。那么相关的样式选项是不同的。因此复制时,应该先同步系列的类型。
4.对于填充,边框等等的样式,除了给series本身设置外,还需要注意给系列中的每个数据点设置。
具体的代码可以参考文末,提供了一个CloneSeries的静态方法。可以复制系列
需要调用的时候,可以通过这句代码
ChartHelper.CloneSeries(chart.SeriesCollection, chart.SeriesCollection);
具体效果:
复制配置前
复制配置后
以下代码为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.Format.Fill, oldSer.Points.Format.Fill);
CloneLine(newSer.Points.Format.Line, oldSer.Points.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.MarkerFormat.Fill, oldSer.Points.MarkerFormat.Fill);
CloneLine(newSer.Points.MarkerFormat.Line, oldSer.Points.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.Format.Fill, oldSer.DataLabels.Format.Fill);
CloneLine(newSer.DataLabels.Format.Line, oldSer.DataLabels.Format.Line);
CloneFont(newSer.DataLabels.Font, oldSer.DataLabels.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.Format.Line, oldSer.Trendlines.Format.Line);
newSer.Trendlines.Type = oldSer.Trendlines.Type;
if (newSer.Trendlines.Type == TrendlineType.MovingAvg)
newSer.Trendlines.Period = oldSer.Trendlines.Period;
if (newSer.Trendlines.Type == TrendlineType.Polynomial)
newSer.Trendlines.Order = oldSer.Trendlines.Order;
newSer.Trendlines.Backward = oldSer.Trendlines.Backward;
newSer.Trendlines.Forward = oldSer.Trendlines.Forward;
newSer.Trendlines.Intercept = oldSer.Trendlines.Intercept;
newSer.Trendlines.DisplayEquation = oldSer.Trendlines.DisplayEquation;
newSer.Trendlines.DisplayRSquared = oldSer.Trendlines.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.Position = oldLabels.Position;
newLabels.ShowValue = oldLabels.ShowValue;
newLabels.ShowCategoryName = oldLabels.ShowCategoryName;
newLabels.ShowSeriesName = oldLabels.ShowSeriesName;
newLabels.ShowLegendKey = oldLabels.ShowLegendKey;
newLabels.Separator = oldLabels.Separator;
newLabels.Position = oldLabels.Position;
newLabels.Text = oldLabels.Text;
newLabels.NumberFormat = oldLabels.NumberFormat;
if (chartType == ChartType.Pie || chartType == ChartType.Doughnut)
newLabels.ShowPercentage = oldLabels.ShowPercentage;
if (chartType == ChartType.Bubble)
newLabels.ShowBubbleSize = oldLabels.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)
{
}
}
页:
[1]