This project has moved. For the latest updates, please go here.

Chart Does not work

Aug 10, 2014 at 5:18 PM
Hi
your library is very good. It is fast and lite.
But when Generate a Document with a chart it damaged and did not open.
I tried your examples but they Did not work neither.
Please help to fix this issue.
Thanks
Developer
Aug 10, 2014 at 5:19 PM
It should work fine in Office 2010 or 2007. For some reason it doesn't work with Office 2013 and it's hard to say why.
Aug 10, 2014 at 5:38 PM
Thanks For your replying.
So is not there any way to fix this bug?
I want open file in office 2013.
Can I change file format from docx to doc fixing this issue?
No body solved this problem?
Developer
Aug 10, 2014 at 6:17 PM
DocX only deals with .docx files. I doubt that changing docx to doc will fix anything. Someone needs to dive into this issue into source code and figure out what could be the problem. So far not many people noticed this bug and I've not seen anyone willing to fix it.
Aug 10, 2014 at 6:30 PM

Just a thought but if no one can fix it then maybe you should just generating the charts outside of docx using .net charting objects, save then as PNG, EMF, etc, then insert into the document at runtime using docx.

This is what we are doing because the chart generation of docx did not give us much control on how it would be displayed, and so far it appears to open properly in office 2013. It’s more work but it gives the user the expected output. The downside is that a user would not be able to modify the chart post docx generation.

max

Developer
Aug 10, 2014 at 6:34 PM
It's one of the options you can "leave" here in the forum for anyone to reuse your solution when nessecary. However I would prefer charts to simply be fixed. Hard to say what have changed between Word 2013 and Word 2010. I guess one wanting to fix it would have to:

a) create very simple chart in Word 2013
b) create very simple chart in Word 2010
c) compare both files (rename docx to .zip and unpack and compare files)
d) see what are differences
e) compare it with the one created in DocX
f) figure it out :-)
Aug 10, 2014 at 7:36 PM
I want to generate a file with more than 100 charts. I used Microsoft office library and it generated more than 50 minutes. after that I generated charts and convert to EMF and then load them into file. but this took more than 10 minute. Now do this with DocX library and take less than 1 minute. Why should I use Microsoft office now? It is not useful.
If it be possible generating charts in DocX every things goes OK.
Is there any library like DocX to be fast?
Aug 10, 2014 at 8:18 PM

Mohammad,

If you are referring to my earlier suggestion unfortunately I cannot speak to your particular use case of 100 charts.

What we did with is our case is utilize the System.Windows.Forms.DataVisualization.Charting; and it did not appear to be slow but or requirements are based on running the process in batch mode hence a few minutes does not have any impact whatsoever.

max

Aug 16, 2014 at 8:00 PM
Edited Aug 16, 2014 at 8:03 PM
Mohammad,

Not sure if you have solved your problem but just in case below is some code that demonstrate how you can insert charts into template. It has worked for us and it might give you some ideas.

To simplify I lifted a sample chart generation in C# from Tim Brass Blog the rest is DocX code

Hopefully you will find it useful

max
using Novacode;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;

namespace DocXSample {
    class Program {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args) {
            System.Diagnostics.Debug.WriteLine("Start..." + DateTime.Now.ToString());

            DocX templateDoc = DocX.Load(@"MyTemplate.docx");     // Load the template 
            templateDoc.ReplaceText("{my-title}", "My Sample Title");

            // Generate 100 charts
            for (int i = 0; i < 100; i++) {
                string chartName = "chart-" + i;

                Program.createChart(templateDoc, chartName);

                Novacode.Image img = templateDoc.AddImage(@chartName + ".png");
                Picture pic = img.CreatePicture();
                pic.Description = chartName + " Description...";
                pic.Title = chartName + " Title...";

                Paragraph p = Program.FindPargraphByTag(templateDoc, "{" + chartName + "}");
                p.InsertPicture(pic, 0);
            }

            templateDoc.SaveAs(@"output.docx");
            System.Diagnostics.Debug.WriteLine("Finished..." + DateTime.Now.ToString());
        }


        /// <summary>
        /// 
        /// </summary>
        private static void createChart(DocX doc, string chartName) {
            System.Diagnostics.Debug.WriteLine("  Creating Chart..." + chartName);


            // *********************************************
            // Start Chart creation
            // source: http://timbar.blogspot.com/2012/04/creating-chart-programmatically-in-c.html
            // set up some data
            var xvals = new[]
                {
                    new DateTime(2012, 4, 4), 
                    new DateTime(2012, 4, 5), 
                    new DateTime(2012, 4, 6), 
                    new DateTime(2012, 4, 7)
                };
            // Original code 
            //var yvals = new[] { 1, 3, 7, 12 };

            // Proivde some randomnes to the charts
            Random rnd = new Random();
            var yvals = new[] { rnd.Next(1, 14),  rnd.Next(1, 14),  rnd.Next(1, 14),  rnd.Next(1, 14) };

            // create the chart
            System.Windows.Forms.DataVisualization.Charting.Chart chart = new System.Windows.Forms.DataVisualization.Charting.Chart();
            chart.Size = new Size(600, 250);

            var chartArea = new ChartArea();
            chartArea.AxisX.LabelStyle.Format = "dd/MMM\nhh:mm";
            chartArea.AxisX.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisY.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisX.LabelStyle.Font = new Font("Consolas", 8);
            chartArea.AxisY.LabelStyle.Font = new Font("Consolas", 8);
            chart.ChartAreas.Add(chartArea);

            var series = new System.Windows.Forms.DataVisualization.Charting.Series();
            series.Name = "Series1";
            series.ChartType = SeriesChartType.FastLine;
            series.XValueType = ChartValueType.DateTime;
            chart.Series.Add(series);

            // bind the datapoints
            chart.Series["Series1"].Points.DataBindXY(xvals, yvals);

            // copy the series and manipulate the copy
            chart.DataManipulator.CopySeriesValues("Series1", "Series2");
            chart.DataManipulator.FinancialFormula(
                FinancialFormula.WeightedMovingAverage,
                "Series2"
            );
            chart.Series["Series2"].ChartType = SeriesChartType.FastLine;

            // draw!
            chart.Invalidate();
            // write out a file
            chart.SaveImage(@chartName + ".png", ChartImageFormat.Png);
            // End Chart creation
            // *********************************************



        }


        /// <summary>
        /// Find a paragraph reference using the tag value
        /// </summary>
        /// <param name="templateDoc"></param>
        /// <param name="tag"></param>
        /// <param name="removeTag"></param>
        /// <returns></returns>
        private static Paragraph FindPargraphByTag(DocX doc, String tag, bool removeTag = true) {

            for (int i = 0; i < doc.Paragraphs.Count; i++) {
                Novacode.Paragraph p = doc.Paragraphs[i];
                string s = p.Text;
                if (p.Text.Equals(tag)) {
                    if (removeTag) p.ReplaceText(tag, " ");
                    return p;
                }
            }
            return null;
        }

    }

}