"The Linked File Isn't Available" Message Appears when Editing Pie Chart Value

Hi Team,

When I try to edit the data of a pie chart after generated using aspose, the following message gets displayed.

Error_PPT.png (5.3 KB)

is there any way to sort this out issue.

Thanks

@Rashique,
Thank you for contacting support.

Please check your results using the latest version of Aspose.Slides for .NET if possible. If the issue persists, please share the following files and information:

  • input files (if you used them)
  • code example that generates the chart
  • output presentation file
  • OS version on which the code was executed
  • .NET target platform in your app
  • Aspose.Slides version you used

Please find the below details and the sample code to generate the chart,

Piechart_Edit.docx (16.8 KB)

  • .NET target platform: .Net 5.0
  • Aspose.Slides version: Aspose.Slides.Net (23.1.0)

@Rashique,
Thank you for the additional information. I will get back to you as soon as possible.

@Rashique,
I’ve reproduced the problem you described.

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): SLIDESNET-44245

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

Hi ,
Please give any update for that ticket pie chart editing we are waiting.

@Rashique,

We’re sorry but your issue wasn’t resolved yet. Once we have an update on it, we will let you know here. We apologize for any inconvenience caused to you.

@Rashique,
Our developers have investigated the case. The issue is caused by this code line:

IChartSeries series = chart.ChartData.Series.Add(fact.GetCell(0, 0, 1, " "), chart.Type);

In this case, the corresponding Excel workbook will be serialized in a table with a header having only " " values. In this case, the Excel workbook is classified as corrupted and cannot be opened (MS Excel also cannot open this workbook and says that it is corrupted).

To fix it, the code line have to be changed as:

IChartSeries series = chart.ChartData.Series.Add(fact.GetCell(0, 0, 1, null), chart.Type);

The null value can be used instead of string.Empty.

In this case, no tables will be created during serializing the workbook, therefore it works.

Also, fact.Clear(0); is added to clear initial values in the workbook (but it’s not mandatory).

Here is the corrected code snippet:

using (Presentation presentation = new Presentation())
{
    ISlide slide = presentation.Slides[0];

    System.Data.DataTable dtClone = new System.Data.DataTable();

    dtClone.Columns.Add("Rating");
    dtClone.Columns.Add("MarketNumber");

    DataRow dr = dtClone.NewRow();
    dr["Rating"] = "Others";
    dr["MarketNumber"] = "91.29";
    dtClone.Rows.Add(dr);

    DataRow dr1 = dtClone.NewRow();
    dr1["Rating"] = "CRISIL";
    dr1["MarketNumber"] = "4";
    dtClone.Rows.Add(dr1);

    DataRow dr2 = dtClone.NewRow();
    dr2["Rating"] = "ICRA";
    dr2["MarketNumber"] = "1.92";
    dtClone.Rows.Add(dr2);

    DataRow dr3 = dtClone.NewRow();
    dr3["Rating"] = "SOV";
    dr3["MarketNumber"] = "1.36";
    dtClone.Rows.Add(dr3);

    DataRow dr4 = dtClone.NewRow();
    dr4["Rating"] = "Care";
    dr4["MarketNumber"] = "0.84";
    dtClone.Rows.Add(dr4);

    DataRow dr5 = dtClone.NewRow();
    dr5["Rating"] = "IND";
    dr5["MarketNumber"] = "0.59";
    dtClone.Rows.Add(dr5);

    dtClone.AcceptChanges();

    IChart chart = slide.Shapes.AddChart(ChartType.Pie, 28, 190, 270, 220);

    CreatePieChart(chart, dtClone, slide);

    presentation.Save(Path.Combine(TestSettings.TestOutPath, "SLIDESNET-44245-output.pptx"), SaveFormat.Pptx);
}

public static IChart CreatePieChart(IChart chart, System.Data.DataTable dt, ISlide slide)
{
    try
    {
        Color[] colorlist = new Color[]
                            {
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102),
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102),
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102),
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102),
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102),
                                Color.FromArgb(40, 60, 131), Color.FromArgb(75, 108, 161), Color.FromArgb(111, 137, 190), Color.FromArgb(139, 151, 188),
                                Color.FromArgb(138, 213, 240), Color.FromArgb(77, 95, 135), Color.FromArgb(199, 201, 221), Color.FromArgb(23, 59, 102)
                            };

        chart.HasTitle = true;
        chart.ChartTitle.TextFormat.PortionFormat.FontHeight = 10;
        chart.ChartTitle.TextFormat.PortionFormat.LatinFont = new FontData("Arial");

        chart.HasLegend = false;
        // Set first series to Show Values
        chart.ChartData.Series[0].Labels.DefaultDataLabelFormat.ShowValue = true;

        // Getting the chart data worksheet
        IChartDataWorkbook fact = chart.ChartData.ChartDataWorkbook;

        // Delete default generated series and categories
        chart.ChartData.Series.Clear();
        chart.ChartData.Categories.Clear();
        fact.Clear(0);

        for (int count = 0; count < dt.Rows.Count; count++)
        {
            DataRow row = dt.Rows[count];
            chart.ChartData.Categories.Add(fact.GetCell(0, count + 1, 0, row[0].ToString()));
        }

        // Adding new series
        IChartSeries series = chart.ChartData.Series.Add(fact.GetCell(0, 0, 1, null), chart.Type);
        // chart.ChartData.Series[0].Labels.Equals("#PERCENT{P2}");
        Aspose.Slides.Charts.IChartDataPoint[] dataPointValues = new Aspose.Slides.Charts.IChartDataPoint[30];

        for (int count = 0; count < dt.Rows.Count; count++)
        {
            DataRow row = dt.Rows[count];
            //chart.ChartData.Categories.Add(fact.GetCell(0, count + 1, 0, row[0].ToString()));
            series.DataPoints.AddDataPointForPieSeries(fact.GetCell(0, count + 1, 1, row[1]));
        }

        series.Labels.DefaultDataLabelFormat.IsNumberFormatLinkedToSource = false;
        //chart.CategoryAxis.TickLabels.SourceLinked = false;
        // series.NumberFormatOfValues = "0.0%";
        series.Labels.DefaultDataLabelFormat.TextFormat.PortionFormat.FontBold = NullableBool.True;
        series.Labels.DefaultDataLabelFormat.TextFormat.PortionFormat.FontHeight = 9;
        series.Labels.DefaultDataLabelFormat.TextFormat.PortionFormat.LatinFont = new FontData("Arial");
        //series.Labels.DefaultDataLabelFormat.ShowPercentage = true;
        series.Labels.DefaultDataLabelFormat.ShowLeaderLines = true;
        series.Labels.DefaultDataLabelFormat.TextFormat.PortionFormat.FillFormat.FillType = FillType.Solid;
        series.Labels.DefaultDataLabelFormat.TextFormat.PortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
        //series.Labels.DefaultDataLabelFormat.TextFormat.AnchoringType = TextAnchorType.Top;
        //series.Labels.DefaultDataLabelFormat.TextFormat.AutofitType = TextAutofitType .None;;
        //series.Labels.DefaultDataLabelFormat.TextFormat.WrapText = NullableBool.False;

        series.Labels.DefaultDataLabelFormat.Position = LegendDataLabelPosition.OutsideEnd;
        //chart.HasLegend = true;
        //chart.Legend.Position = Aspose.Slides.Charts.LegendPositionType.Bottom;

        chart.ChartData.SeriesGroups[0].IsColorVaried = true;
        for (int pnt = 0; pnt < series.DataPoints.Count; pnt++)
        {
            if (Convert.ToDouble(series.DataPoints[pnt].Value.Data.ToString()) > 0.00)
            {
                Aspose.Slides.Charts.IChartDataPoint point = series.DataPoints[pnt];
                chart.ChartData.Series[0].NumberFormatOfValues = "\"" + string.Join(",", series.DataPoints[pnt].Value.Data.ToString() + " %") + "\"";
                point.Label.DataLabelFormat.NumberFormat = chart.ChartData.Series[0].NumberFormatOfValues;
                point.Format.Line.FillFormat.FillType = FillType.Solid;
                point.Format.Line.FillFormat.SolidFillColor.Color = Color.White;
                point.Format.Line.Width = 2.0;
                point.Format.Line.Style = LineStyle.Single;
                point.Label.DataLabelFormat.ShowCategoryName = true;
                // point.Label.DataLabelFormat.ShowLegendKey = true;
                point.Label.DataLabelFormat.ShowValue = true;

                point.Format.Fill.FillType = FillType.Solid;
                point.Format.Fill.SolidFillColor.Color = colorlist[pnt];

                chart.ChartTitle.TextFormat.PortionFormat.LatinFont = new FontData("Arial");
                //lbl.DataLabelFormat.ShowSeriesName = true;

                // Store the data in a variable
                IDataLabel lbl = series.DataPoints[pnt].Label;
                lbl.DataLabelFormat.ShowBubbleSize = false;
                IDoubleChartValue value = series.DataPoints[pnt].Value;
                // Convert the value to integer
                int intValue = Convert.ToInt32(value.ToDouble());

                //if (intValue < 10)
                //{
                //    lbl.DataLabelFormat.Position = LegendDataLabelPosition.BestFit;
                //}
                //else
                //{
                lbl.DataLabelFormat.Position = LegendDataLabelPosition.OutsideEnd;
                //}
            }
        }

        chart.ChartData.SeriesGroups[0].FirstSliceAngle = 360;
    }
    catch (Exception ex)
    {
    }

    return chart;
}

Since System.Data.DataTable cells are of type object, the data will be saved in a general format (rather than numeric) in the linked Excel worksheet.

Once you edit it, the chart data will be updated from the associated Excel sheet and disappear. To avoid it, the data should be specified using the specific type, not the object.
For example the following line

series.DataPoints.AddDataPointForPieSeries(fact.GetCell(0, count + 1, 1, row[1]));

should be replaced with

series.DataPoints.AddDataPointForPieSeries(fact.GetCell(0, count + 1, 1, double.Parse(row[1].ToString())));

or using more suitable conversion method.