-
Notifications
You must be signed in to change notification settings - Fork 2
Analysis
BizDoc analysis cube.
DI IAnalysisService.
Positions, Patterns or none. Set Cube Scope property in bizdoc.json file.
{
"Mode": "Positions"
}"Cubes": [
{
"Axes": [
{
"DataType": "years",
"Name": "year",
"Title": "Year"
},
{
"DataType": "quarters",
"Name": "quarter",
"Title": "Quarter"
}
],
"Views": [
{
"XAxis": [
"year",
"month"
],
"Series": "balance",
"Indices": "budget",
"ChartType": "StackingColumn",
"Name": "balance",
"Title": "Balance"
}
],
"Indices": [
{
"Name": "budget",
"Title": "Budget"
}
],
"Name": "myCube",
"Title": "My cube"
}]bizdoc.json
"Cubes": [
{
"Name": "cube-1",
"Title": "Cube 1",
"Views": [
{
"XAxis": "quarter",
"Series": [
"year",
"month"
],
"ChartType": "Bar",
"Type": "Pivot",
"Name": "view1",
"Title": "Q / Y"
}
]
}
]Properties
| Name | Usage |
|---|---|
| Type | One of Chart, Pivot, Spreadsheet or Grid |
| ChartType | One of Line, Column, Area, Bar, StackingColumn, StackingArea, StackingBar, StepLine, StepArea, SplineArea, Scatter, Spline, StackingColumn100, StackingBar100, StackingArea100, Bubble, Pareto, Polar, Radar, Pie, Pyramid, Doughnut or Funnel. Default to Column. |
Chart type can be set for Pivot or Chart.
[CubeMapping(nameof(Year), nameof(Quarter), nameof(Month), nameof(Balance))]
public class Line {
public DateTime Date { get; set; }
[JsonIgnore, ListType(typeof(Years))]
public short Year => (short)Date.Year;
[JsonIgnore, ListType(typeof(Months))]
public byte Month => (byte)Date.CubeMonth(); // extension method
[JsonIgnore, ListType(typeof(Quarters))]
public byte? Quarter => Date.Quarter(); // extension method
[ListType(typeof(Balances)), ValueResolver(typeof(StateAxisResolver<Balance?>))]
public Balance? Balance { get; set; }
[Value, JsonIgnore]
public decimal Total => Amount * Qty;
public decimal Amount { get; set; }
public decimal Qty { get; set; }
}The Value attribute directs BizDoc which property holds the cube value. You can also set the Currency, ExchangeRate and Percentage attributes.
The StateAxisResolver above finds the Balance in the configuration file that matches the document state. Set the Axis attribute of state Options:
CubeMappingaxes should match the ordinal of the Axes declared in configuration file.
public class PurchaseModel {
[CurrencyCode]
string CurrencyCode { get; set; }
string SiteId {get;set;}
IEnumberable<Line> Lines { get ;set; }
public class Line {
public string DepartmentId { get; set; }
public Date RequestDate { get; set; }
public Date DueDate { get; set; }
IEnumberable<Expense> Expenses { get ;set; }
[CubeMapping(nameof(PurchaseModel.SiteId), nameof(DepartmentId), nameof(Quarter)]
public class Expense {
[JsonIgnore]
public byte Quarter => ExpenseDate.Quarter();
public Date ExpenseDate { get; set; }
}
}
}public class PurchaseBackend : FormBase<PurchaseModel> {
public override Task UpdateAsync(model: PurchaseModel, oldModel: PurchaseModel) {
foreach(var line in model.Lines) {
var expenses = new List<PurchaseModel.Line.Expense>();
var date = line.RequestDate;
do {
expenses.Add(new PurchaseModel.Line.Expense { ExpenseDate = date });
date.addMonth(1);
} while(date < line.DueDate);
line.expenses = expenses;
}
}
}Declare a model for your 3rd party objects (PO, etc.).
public class PO {
}Override the ExploreType() method in cube object and return the model type if request matches the axes.
public class MyCube : AnalysisBase, AnalysisBase.IBrowsable<PO> {
private const byte BalanceAxisPosition = 4;
public override ExploreType(params string[] axes) {
if (axes.ElementAt(BalanceAxisPosition).
Equals(Balance.PO.ToString())
return typeof(PO);
return base.ExploreType();
}
}Then, implement the AnalysisBase.IBrowsable<T> QueryAsync() on the cube object to populate the 3rd party data.
public class MyCube : AnalysisBase, AnalysisBase.IBrowsable<PO> {
public override async Task<IEnumerable<PO>> QueryAsync(params Axis[][] axes) {
...
}
}The QueryAsync implementation should be able to handle different Axis kinds, including range, arrays and patterns. Use the FormatAxesPhrase() method of to build an SQL phrase that supports these patterns.
A cube may declare patterns. Each pattern represents a set of axes values which can be assigned permissions to one or more user roles and rules.
Use patterns to restrict access to cube data. For example, to restrict view to years 20` for companies 201 and 202 and regions 11 through 99 to system role, add the following configuration:
"Patterns": [
{
"Axes": {
"year": "20*",
"company": [201, 202],
"region": "11-99"
},
"Roles": [
"System"
],
"Name": "y2",
"Title": "20`"
}
]Mask value accepts a dot (.) for a single character, asterisk (*) for more than one character and hashtag (#) for replacing an individual character with a character at the same position in a previously selected combination. Hashtags patterns enable drilling up from a base combination.
In addition to roles, a pattern can be set a programmatic rule expression. See Rules section on how to add an expression.
The built-in CubePatternUsage report uses patterns to selectively show data relevant to the user.
You can test if the user has privileges to a certain set of axes using the Authorize() method of the AnalysisService service.
By default, the cube CanView() method uses patterns to restrict access to cube data.
Patterns can be modified using the designated administration utility or by manually editing the configuration file.
Angular:
@Injectable()
export class MyService {
private readonly _service = inject(AnalysisService);
}Server:
public class MyClass(IAnalysisService analysisService) {
public Task<IDictionary> GetDepartments () => analysisService.GetValuesAsync()
}| Table | Usage |
|---|---|
| Entries | Cube Axes mapping for a document |
| Cube | Reflects document data from Entries table and data from 3rd party app |
| Indices | Indices for cube |
| Segments | Account segments code names (default implementation) | Combinations | Account segments combinations (default implementation)
As Cube and Indices tables grow significantly large, consider adding indexes to the axes you are using to filter requests.
Handles.
Methods
| Name | Usage |
|---|---|
| Contains(Axis) | |
| Join(Axis) | |
| Combine(params Axis[]) | |
| FromValue(value) | Static |
| FromRange(start, end) | Static |
| FromArray(params value[]) | Static |
| Negate() | |
| Unwrap(params chars[]) | |
| Equals(Axis) | |
| IsInclusive | |
| IsEmpty |
To create an axis expression of range 1-3, but not 2, use:
Axis.Combine(Axis.FromRange(1, 3), Axis.FromValue(2).Negate());Moding Ltd.