Difference between revisions of "Tabulation Script"
m |
m (→Document revisions) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 44: | Line 44: | ||
Interpreter cgsEngine = dcs.GetReportInterpreter(); | Interpreter cgsEngine = dcs.GetReportInterpreter(); | ||
</source> | </source> | ||
+ | |||
+ | === Class diagram === | ||
+ | [[Image:Diagram_-_Tabulation_Script.gif]] | ||
+ | |||
+ | To not making too many changes at the same time, only class ''CGScript_System_Report'' is copied from ''CatGlobe'' to ''CatGlobe.Report''. The remaining classes are still inside ''CatGlobe''. | ||
=== Point of injections === | === Point of injections === | ||
+ | |||
+ | ==== ''Interpreter'' ==== | ||
+ | ''Interpreter'' now must support for an additional constructor which received custom libraries as below: | ||
+ | <source lang="csharp"> | ||
+ | internal Interpreter(IEnumerable<CGScriptLibrary> additionalLibraries) | ||
+ | : this() | ||
+ | { | ||
+ | Debug.Assert(SymbolTable != null); | ||
+ | if (additionalLibraries != null) | ||
+ | foreach (CGScriptLibrary library in additionalLibraries) | ||
+ | if (library != null) | ||
+ | library.Register(SymbolTable); | ||
+ | } | ||
+ | |||
+ | public Interpreter() | ||
+ | { | ||
+ | cultureInfo = CultureInfo.InvariantCulture; | ||
+ | formatter = cultureInfo.NumberFormat; | ||
+ | symbolTable = new SymbolTable(true); | ||
+ | input = string.Empty; | ||
+ | cgScriptCompiler = new ILCodeGenerator(symbolTable); | ||
+ | IsInCellCalculationMode = false; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | * Modifier of this constructor is ''internal'' to prevent non-friend code to access it | ||
+ | * The constructor call its counterpart which receives no parameter and create instance of symbolTable | ||
+ | * Then, for each assembly, register it with the created symbol table. Because symbol table use dictionary as its data store, so the newer registered function would override the existing one. This allow us new engine's scripts override old engine's scripts. | ||
==== ''TabulationDiagram'' ==== | ==== ''TabulationDiagram'' ==== | ||
As shown in processing of tabulation script section above, the main idea of ''TabulationDiagram'' is that it is created with enough information for generating a domain's diagram instance, but that instance is created whenever needed only. | As shown in processing of tabulation script section above, the main idea of ''TabulationDiagram'' is that it is created with enough information for generating a domain's diagram instance, but that instance is created whenever needed only. | ||
− | So, to inject our processing with least painful, I decided to create a diagram | + | So, to inject our processing with least painful, I decided to create a diagram factory delegate. The delegate type is declared in ''DiagramUtility'' class (''CatGlobe'' assembly) but the implementation is inside ''CatGlobe.Report'' assembly. After all, the instance of the delegate will be passed to ''CatGlobe'' from ''CatGlobe.Report'' during execution of a tabulation script. And the ''TabulationDiagram'' is changed as below: |
<source lang="csharp"> | <source lang="csharp"> | ||
public Diagram InternalDiagram | public Diagram InternalDiagram | ||
Line 80: | Line 113: | ||
</source> | </source> | ||
− | It can be understood as if there is a custom diagram | + | It can be understood as if there is a custom diagram factory delegate, use that. Otherwise, use the default method. |
==== ''CatGlobe.Report'''s code ==== | ==== ''CatGlobe.Report'''s code ==== | ||
− | First of all, we need an implementation of the diagram | + | First of all, we need an implementation of the diagram factory delegate: |
<source lang="csharp"> | <source lang="csharp"> | ||
Line 115: | Line 148: | ||
| '''Changed By''' | | '''Changed By''' | ||
| '''Description''' | | '''Description''' | ||
+ | | '''Svn Revision''' | ||
|- | |- | ||
| 0.1 | | 0.1 | ||
Line 120: | Line 154: | ||
| Nguyen Trung Chinh | | Nguyen Trung Chinh | ||
| Create the first version | | Create the first version | ||
+ | | NA | ||
+ | |- | ||
+ | | 0.1 | ||
+ | | 23.07.2009 | ||
+ | | Nguyen Trung Chinh | ||
+ | | Finish first version | ||
+ | | 54885 | ||
|} | |} |
Latest revision as of 08:33, 4 August 2009
New Report Design - 2009 => Tabulation Script
Contents
Tabulation Script
Tabulation Script is a CGScript library allowing user to create diagram/report. It's also capable of setting stylesheet (both external and internal).
Some classes
- CGScript_System_Report: CGScript library implementation, contains all entry points to diagram/report generation process
- TabulationModuleUtilities: contains utility methods
- DiagramUtilities: also contains utility methods
- TabulationDiagram: wrapper class for the REAL report diagram
- TabulationConfiguration: contains all result of tabulation diagram (the name ??!!!!)
Understanding tabulation script processing
The processing of tabulation script can be understand as below:
- Create new Interpreter (which create also an instance of TabulationConfiguration as properties named TabulationConfig )
- Run the tabulation script => the result diagrams (if any) is stored inside DiagramCharts variable of TabulationConfiguration
- If has to show result, get the result diagram objects from DiagramCharts and set to session
- Show a SPECIFIC viewer that takes diagram objects from session and draw on screen (why do we need a SPECIFIC viewer?)
Injecting new processing with least impact
Moving script location
Due to the fact that tabulation script belongs to REPORT DOMAIN rather RUNTIME DOMAIN, it MUST be in the same assembly with REPORT. And to not change so much at the same time, the file CGScript_System_Report is 'copied' to CatGlobe.Report assembly under folder Script. The namespace was also changed to CatGlobe.Framework.Report.Script.
CGScript engine is designed to hide all unnecessary information from the outside (good point). But we need references to some internal classes in order to implement a CGScriptLibrary. Thus, the CatGlobe assembly must be internal visible to CatGlobe.Report.
And, there must be a factory method for getting Interpreter that can support for report:
public static class ScriptLibraryHelper
{
public static Interpreter GetReportInterpreter(this DataCacheSpecification dataCache)
{
return new Interpreter(new[] { CGScript_System_Report.Instance })
{
DataCacheSpecification = dataCache,
};
}
}
That's mean, with a appropriate using statement, we can create report's interpreter as below:
DataCacheSpecification dcs = DataCacheSpecification.GetBy(1);
Interpreter cgsEngine = dcs.GetReportInterpreter();
Class diagram
To not making too many changes at the same time, only class CGScript_System_Report is copied from CatGlobe to CatGlobe.Report. The remaining classes are still inside CatGlobe.
Point of injections
Interpreter
Interpreter now must support for an additional constructor which received custom libraries as below:
internal Interpreter(IEnumerable<CGScriptLibrary> additionalLibraries)
: this()
{
Debug.Assert(SymbolTable != null);
if (additionalLibraries != null)
foreach (CGScriptLibrary library in additionalLibraries)
if (library != null)
library.Register(SymbolTable);
}
public Interpreter()
{
cultureInfo = CultureInfo.InvariantCulture;
formatter = cultureInfo.NumberFormat;
symbolTable = new SymbolTable(true);
input = string.Empty;
cgScriptCompiler = new ILCodeGenerator(symbolTable);
IsInCellCalculationMode = false;
}
- Modifier of this constructor is internal to prevent non-friend code to access it
- The constructor call its counterpart which receives no parameter and create instance of symbolTable
- Then, for each assembly, register it with the created symbol table. Because symbol table use dictionary as its data store, so the newer registered function would override the existing one. This allow us new engine's scripts override old engine's scripts.
TabulationDiagram
As shown in processing of tabulation script section above, the main idea of TabulationDiagram is that it is created with enough information for generating a domain's diagram instance, but that instance is created whenever needed only.
So, to inject our processing with least painful, I decided to create a diagram factory delegate. The delegate type is declared in DiagramUtility class (CatGlobe assembly) but the implementation is inside CatGlobe.Report assembly. After all, the instance of the delegate will be passed to CatGlobe from CatGlobe.Report during execution of a tabulation script. And the TabulationDiagram is changed as below:
public Diagram InternalDiagram
{
get
{
if (this.internalDiagram == null)
this.CreateInternalDiagram();
return this.internalDiagram;
}
set { this.internalDiagram = value; }
}
private void CreateInternalDiagram()
{
...
InternalDiagram = DiagramFactoryMethod != null
? DiagramFactoryMethod(this.ReportTemplate, this.ChartName, DiagramType.CrossDiagram, this.ChartType, string.Empty, this.Parameter)
: DiagramUtilities.CreateDiagram(this.ReportTemplate
, this.CrossStruct
, this.ChartName
, this.Generator.Header
, this.Generator.Title
, this.Generator.Parameter.ChartType
, DiagramType.CrossDiagram
, subtitle1, string.Empty, string.Empty);
...
}
It can be understood as if there is a custom diagram factory delegate, use that. Otherwise, use the default method.
CatGlobe.Report's code
First of all, we need an implementation of the diagram factory delegate:
// CatGlobe.Report assembly
public static class DomainDiagramFactory
{
public static Domain.Reports.Diagram CreateDiagram(
ReportTemplate template, string chartName, DiagramType diagramType,
ChartType chartType, string weight, Parameter parameter)
}
Then, we need to transfer above delegate instance to CatGlobe assembly;
internal sealed class CGScript_System_Report : CGScriptLibrary
{
private static int CreateDiagram(List<Axis> columns, List<Axis> rows, FunctionIdentifier function)
{
...
TabulationDiagram diagram = TabulationModuleUtilities.CreateDiagramObject(crossStruct, config, DomainDiagramFactory.CreateDiagram);
...
}
}
Document revisions
Version No. | Date | Changed By | Description | Svn Revision |
0.1 | 23.07.2009 | Nguyen Trung Chinh | Create the first version | NA |
0.1 | 23.07.2009 | Nguyen Trung Chinh | Finish first version | 54885 |