1

我正在使用 NReco 库来构建数据透视表。我正在按照示例进行操作,并且能够从 DataSet 构建一个简单的 PvT。现在我想构建一个 PvT,它接收在运行时选择的许多度量值,但是我在使用度量值列表的过程的动态性质方面遇到了麻烦,每个度量值都有自己的聚合公式。该公式在运行时是已知的,它只不过是一个总和或一个平均值,但特定于度量。我有以下代码:

private string CreatePivotTable(DataTable dt, string[] lines, string[] columns, string[] dimensions, string measure)
    {

        var pivotData = new PivotData(dimensions, new SumAggregatorFactory(measure), new DataTableReader(dt));

        var pivotTable = new PivotTable(lines, columns, pivotData);
        var htmlResult = new StringWriter();
        var pvtHtmlWr = new PivotTableHtmlWriter(htmlResult);
        pvtHtmlWr.Write(pivotTable);

        return htmlResult.ToString();
    }

我想做类似下面的代码来在运行时动态添加度量和聚合器:

 private string CreatePivotTable(DataTable dt, string[] lines, string[] columns, string[] dimensions, Measure[] measures)
    {


        var pivotData = new PivotData(dimensions, null, new DataTableReader(dt));

        foreach(var m in measures)
        {
            if (m.Formula.equals("sum"))
                pivotData.AggregatorFactory.Create(new SumAggregator(m.ColName));
            else if(m.Formula.equals("avg")){
             pivotData.AggregatorFactory.Create(new AvgAggregator(m.ColName));
           }
        }
     }

我怎样才能实现这样的目标?有没有办法做到这一点?

4

1 回答 1

0

您可以通过以下方式配置PivotData类以收集多个度量值:

private string CreatePivotTable(
    DataTable dt, string[] lines, string[] columns, string[] dimensions, Measure[] measures)
{
    var aggrFactories = new List<IAggregatorFactory>();
    foreach(var m in measures) {
        if (m.Formula.equals("sum"))
            aggrFactories.Add( new SumAggregatorFactory(m.ColName));
        else if(m.Formula.equals("avg")){
            aggrFactories.Add( new AverageAggregatorFactory(m.ColName));
        }
    }
    if (aggrFactories.Length==0) {
        // no measures provided. 
        // Throw an exception or configure "default" measure (say, CountAggregatorFactory)
        aggrFactories.Add( new CountAggregatorFactory() );
    }   
    var pivotData = new PivotData(dimensions, 
        aggrFactories.Length==1 ? aggrFactories[0] : new CompositeAggregatorFactory(aggrFactories.ToArray()),
        new DataTableReader(dt));
    // you code that renders HTML pivot table with PivotTableHtmlWriter
}

作为替代方案,您可以使用可以按模型创建实例的PivotDataFactory组件(NReco.PivotData.Extensions 程序集) :PivotDataPivotDataConfiguration

private string CreatePivotTable(DataTable dt, string[] lines, string[] columns, string[] dimensions, Measure[] measures)
{
    var pvtDataFactory = new PivotDataFactory();
    var pivotData = pvtDataFactory.Create( new PivotDataConfiguration() {
        Dimensions = dimensions,
        Aggregators = measures
            .Select(m => new AggregatorFactoryConfiguration(m.Formula, new[] {m.ColName}) )
            .ToArray()
    });
    // you code that renders HTML pivot table with PivotTableHtmlWriter
}

PivotDataFactory了解标准聚合器类型(“Count”、“Sum”、“Average”、“Min”、“Max”),如果您使用自定义实现,您可以使用方法注册它们(有关详细信息,PivotDataFactory.RegisterAggregator请参阅实现自定义聚合器)。

顺便说一句,真正的用户定义公式(可以使用聚合器值作为参数)也是可能的:请参阅 PivotData SDK 示例包中的“DynamicFormulaMeasure”示例。

于 2017-07-15T07:11:30.813 回答