📦 Colosoft.Data.Analytics.Gateway.Client

Exemplos de uso do Gateway.Client

Trechos de código reais mostrando como descrever schemas de cubo, relatórios pivot com gráficos, relatórios tabulares e fontes de dados usando a API fluente da biblioteca cliente .NET do Colosoft DataAnalytics.

Os trechos abaixo foram adaptados de cube definitions reais construídas com o Gateway.Client dentro do Colosoft WebGlass, um ERP que usa este Gateway como seu backend de análise de dados. A integração da aplicação hospedeira (carregar definições, resolver opções de filtro, executar a consulta SQL etc.) é específica de cada aplicação — o que importa aqui é a API fluente que a biblioteca cliente expõe para descrever schemas, relatórios e gráficos.

1Definindo o schema do cubo

Um ICubeSchema declara as dimensões (eixos categóricos) e as medidas (valores agregados) disponíveis para os relatórios do cubo, construído com CubeSchemaBuilder.

CubeSchemaBuilder

dimensões, medidas e condição de filtro
ClientesCubeDefinition.cs
using Colosoft.Data.Analytics.Gateway.Client;

ICubeSchema schema = new CubeSchemaBuilder()
    .AddDimension("IdCliente")
    .AddDimension("Nome")
    .AddDimension("TipoCliente")
    .AddDimension("Uf")
    .AddDimension(
        "Situacao",
        filterMap: new Dictionary<string, string>
        {
            ["Ativo"] = "0",
            ["Inativo"] = "1",
        })
    .AddCount("Count")
    .AddSum("SumOfLimite", "Limite")
    .AddSum("SumOfUsoLimite", "UsoLimite")
    .AddCondition(filterExpression)
    .Build();
AddDimension declara um eixo do cubo — opcionalmente mapeando valores brutos armazenados para rótulos de exibição através de filterMap — enquanto AddCondition anexa uma expressão de filtro avaliada linha a linha durante a compilação do cubo.

Dimensão computada + medida com agregação SQL customizada

expressão SQL, filterMap + labelMap combinados, AddMeasure genérico
PedidosCubeDefinition.cs
ICubeSchema schema = new CubeSchemaBuilder()
    // dimensão computada via expressão SQL, com tradução de valor em ambas as direções
    .AddDimension(
        "MesDataCadastro", CubeDimensionType.Field,
        new[] { "LPAD(MONTH(DataCadastro), 2, '0')" }, "Mês Cadastro",
        filterMap: meses.ToDictionary(f => f.Nome, f => f.Numero.ToString("00")),
        labelMap: meses.ToDictionary(f => f.Numero.ToString("00"), f => f.Nome))
    // medida com expressão de agregação SQL customizada (AddMeasure genérico + FirstValue)
    .AddMeasure(
        "SumOfPercentualRentabilidade",
        CubeMeasureType.FirstValue,
        parameters: new[] { "SUM(ValorRentabilidade) / SUM(TotalPedido) * 100" },
        labelText: "Percentual Rentabilidade")
    .Build();
Uma dimensão não precisa mapear diretamente uma coluna — o segundo argumento (parameters) aceita fragmentos SQL arbitrários. O mesmo vale para medidas: além dos atalhos AddCount/AddSum/AddAverage/AddMin/AddMax, o AddMeasure genérico aceita qualquer CubeMeasureType — aqui, FirstValue com uma expressão de agregação SQL própria.
AddDimension(name, ...)Declara um eixo categórico do cubo, simples ou computado via expressão SQL
AddCount / AddSum / AddAverageAtalhos para as medidas mais comuns
AddMin / AddMax / AddFirstValueOutros atalhos de medida disponíveis
AddMeasure(name, type, ...)Forma genérica — qualquer CubeMeasureType, incl. expressões customizadas
AddCondition(expression)Filtro aplicado na compilação do cubo
filterMap / labelMapTradução de valor bruto ↔ rótulo de exibição, nos dois sentidos

2Relatórios pivot com gráficos

PivotReportBuilder compõe linhas/colunas (AddRow/AddColumn), medidas (AddMeasure), ordenação, rótulos e paginação. ChartType + Chart(...) descrevem como os mesmos dados devem ser visualizados (eixos, cores, legenda, toolbar, data labels, zoom, animações), e JavaScriptNumberFormat anexa uma formatação numérica por medida, avaliada no cliente.

Indicador único (KPI)

ChartType("singleValue")
ClientesCubeDefinition.cs
IPivotReport totalClientes = new PivotReportBuilder()
    .Id("quantidadeClientes")
    .Name("Clientes")
    .AddMeasure("Count")
    .ChartType("singleValue")
    .Build();

Percentual em barra empilhada horizontal

Percentage + JavaScriptNumberFormat
ClientesCubeDefinition.cs
IPivotReport clientesPorTipo = new PivotReportBuilder()
    .Id("tipoCliente")
    .Name("Tipo Cliente")
    .AddRow("TipoCliente")
    .AddMeasure(m => m.Name("Count").Percentage(PercentageMode.ColumnTotal))
    .ChartType("horizontalStackedBar")
    .Chart(chart => chart.XAxis(axis => axis.Labels(label => label.Show(false))))
    .Labels(otherText: null, emptyText: "Sem tipo")
    .OrderBy(o => o.Values(TableAxis.Rows, null, ListSortDirection.Descending, 0))
    .JavaScriptNumberFormat(0, f => f
        .Locale("pt-BR")
        .MinimumFractionDigits(2)
        .MaximumFractionDigits(2)
        .Suffix("%"))
    .Build();

Pivot bidimensional com heatmap

linhas × colunas, Heatmap por linha
LeiturasPecaSetorDiaCubeDefinition.cs
IPivotReport producaoPorHora = new PivotReportBuilder()
    .Id("producaoPorHora")
    .Name("Produção por Hora")
    .AddRow("SetorSequencial", labelText: "Setor", allowFilter: false)
    .AddColumn("HoraDataLeitura", " ", allowFilter: false, format: "{0}h")
    .Labels(otherText: null, emptyText: " ", totalsRowText: "Totais", totalsColumnText: "Totais")
    .AddMeasure(m => m
        .Name("SumOfMetragemQuadrada")
        .Heatmap(HeatmapMode.Row)
        .HeatmapColor(0x0000FF.ToString())
        .Format("{0:#0.00}"))
    .JavaScriptNumberFormat(0, f => f.Locale("pt-BR").MaximumFractionDigits(2).Suffix(" m²"))
    .Build();

Gráfico de barras com cores customizadas

Colors, toolbar oculto, sem data labels
LeiturasPecaSetorDiaCubeDefinition.cs
IPivotReport capacidadeLida = new PivotReportBuilder()
    .Id("capacidadeLida")
    .Name("Previsto/Realizado Por Setor")
    .AddColumn("NumeroSequenciaSetor", format: "{0:#00}")
    .AddColumn("Setor")
    .AddMeasure(m => m.Name("MaxOfCapacidadeDiaria").LabelText("Capacidade"))
    .AddMeasure(m => m.Name("SumOfMetragemQuadrada").LabelText("Lida"))
    .ChartType("bar")
    .Chart(chart => chart
        .Colors(new[] { "#F08C41", "#118DFF", "#4CBA36", "#991717" })
        .Chart(c => c.Toolbar(t => t.Show(false)))
        .DataLabels(d => d.Enabled(false)))
    .Build();

Hierarquia de linhas com expand/collapse e total acumulado

3 níveis de linha, ExpandCollapse, RunningTotal, legenda customizada
RentabilidadePedidosCubeDefinition.cs
IPivotReport rentabilidadePorCliente = new PivotReportBuilder()
    .Id("rentabilidadePorCliente")
    .Name("Rentabilidade por Cliente")
    .AddRow("DescricaoProduto", labelText: "Produto")
    .AddRow("Rota", labelText: "Rota")
    .AddRow("Cliente", labelText: "Cliente")
    .ExpandCollapse(true)
    .AddMeasure(m => m
        .Name("SumOfValorRentabilidade")
        .LabelText("Acumulado")
        .RunningTotal(RunningValuePivotTableDirection.Row))
    .ChartType("line")
    .Chart(chart => chart.Legend(legend => legend
        .Position(LegendPosition.Bottom)
        .ShowForSingleSeries(true)))
    .OrderBy(o => o.Values(TableAxis.Rows, null, ListSortDirection.Descending, 0))
    .Build();
Empilhar várias chamadas de AddRow (ou AddColumn) cria uma hierarquia navegável; ExpandCollapse(true) habilita a expansão/recolhimento interativo de cada nível no cliente. RunningTotal acumula o valor da medida ao longo do eixo escolhido (aqui, por linha).
AddRow / AddColumnEixos do pivot (com format, labelText, allowFilter) — empilháveis em hierarquia
AddMeasure(m => ...)Nome, formato, percentual, heatmap, diferença, total acumulado
ExpandCollapse(bool)Habilita expansão/recolhimento interativo de hierarquias
OrderBy(o => ...)Ordena por rótulo de dimensão ou por valor de medida
ChartType / Chart(...)Tipo de gráfico e configuração visual completa (eixos, legenda, cores, toolbar...)
JavaScriptNumberFormatFormatação numérica por medida, avaliada no cliente

3Relatório tabular

TableReportBuilder descreve uma listagem plana e não agregada sobre a mesma fonte — tipicamente usada para grades de detalhamento — reaproveitando as mesmas convenções de formatação de coluna do PivotReportBuilder.

TableReportBuilder

colunas formatadas + limite de linhas
ClientesCubeDefinition.cs
ITableReport detalhamentoCliente = new TableReportBuilder()
    .Id("detalhamento")
    .Name("Detalhamento do cliente")
    .AddColumn("IdCliente")
    .AddColumn("Nome", labelText: "Cliente")
    .AddColumn("CpfCnpj", labelText: "Cpf/Cnpj")
    .AddColumn("DataCadastro", format: "{0:dd/MM/yyyy}")
    .AddColumn("Situacao")
    .LimitRows(1)
    .Build();

Grade com totais no rodapé

isTotal + AddOrderBy
PedidosEmitidosCubeDefinition.cs
ITableReport itensPedido = new TableReportBuilder()
    .Id("itensPedido")
    .Name("Itens do Pedido")
    .AddColumn("Peso", format: "{0:#0.00}", isTotal: true)
    .AddColumn("TotalPedido", labelText: "Total do Pedido", format: "{0:C}", isTotal: true)
    .AddOrderBy("DataCadastro", ListSortDirection.Descending)
    .LimitRows(50)
    .Build();
isTotal: true marca uma coluna numérica para ser somada como total no rodapé da grade — útil em listagens de itens/lançamentos.
AddColumn(name, labelText, format, isTotal)Coluna da grade, com total opcional no rodapé
LimitRows / OffsetRowsPaginação simples do relatório tabular
AddOrderBy / ClearOrderByOrdenação das linhas por coluna

4Descrevendo a fonte de dados

SourceDatabaseBuilder envolve a consulta que alimenta o cubo, e DataReaderProviderBuilder.Column permite pós-processar colunas individuais — por exemplo, traduzindo um status numérico armazenado em um rótulo de exibição — antes que o valor chegue ao motor do cubo.

SourceDatabaseBuilder + DataReaderProviderBuilder

coluna com pós-processamento
ClientesCubeDefinition.cs
ISourceDatabase source = new SourceDatabaseBuilder()
    .Configure(query) // consulta expondo as colunas declaradas no schema
    .DataReaderProvider(builder => builder
        .Column(
            "Situacao",
            (_, value) => ((SituacaoCliente)Convert.ToInt32(value)).Translate().Format()))
    .Build();
Configure(query)Consulta que alimenta o cubo (qualquer objeto expondo as colunas do schema)
DataReaderProvider(builder => ...)Pós-processamento coluna a coluna antes de chegar ao motor do cubo
AddJoin(joinSql, campos)Anexa um fragmento SQL de join e os campos que ele expõe
ReadMaxIterations(int)Limite de leitura em lotes da fonte de dados

5Conectando e compilando em tempo real

Com o schema, a fonte e os relatórios descritos, falta empacotar tudo em um IDatabaseCube e conectar ao Gateway. CubeCompilerFactory abre uma conexão SignalR com o Gateway; ICubeCompiler.Compile compila o cubo contra um ou mais relatórios e devolve o resultado — em HTML, Excel, CSV ou JSON — através de um ICubeCompilerObserver.

Fluxo completo: cubo → conexão → compilação

DatabaseCubeFactory + CubeCompilerFactory + CubeCompilerObserver
ExportReportCommand.cs
// 1. Empacota schema + fonte + conexão em um cubo
var cubeFactory = new DatabaseCubeFactory();
IDatabaseCube cube = cubeFactory.Create(
    schema,
    source,
    cancellationToken => Task.FromResult<IDbConnection>(connection),
    leaveOpen: true);

// 2. Abre a conexão SignalR com o Gateway
var compilerFactory = new CubeCompilerFactory(
    "https://seu-gateway/gateway/cubecompiler",
    authenticator); // null se o Gateway não exigir autenticação

using (var compiler = await compilerFactory.Create(CultureInfo.GetCultureInfo("pt-BR"), cancellationToken))
{
    // 3. Registra um observer para receber o resultado compilado
    compiler.Add(new CubeCompilerObserver(
        onResultItem: async (compiledReport, content, contentType, ct) =>
        {
            // content: Stream com o relatório compilado, no formato pedido abaixo
        }));

    // 4. Compila o cubo contra um ou mais relatórios de uma vez
    await compiler.Compile(
        cube,
        new[] { new CubeCompilerReport(report, CubeCompilerReportOutputType.Html) },
        cancellationToken);
}
ICubeCompiler é IDisposable — sempre use using. Uma única chamada a Compile pode receber vários CubeCompilerReport/ CubeCompilerTableReport, cada um com seu próprio CubeCompilerReportOutputType (Json, Html, Excel ou Csv) — o observer é chamado uma vez por relatório compilado.
DatabaseCubeFactory.Create(...)Cria o IDatabaseCube a partir de schema + fonte + conexão
CubeCompilerFactory.Create(...)Abre a conexão SignalR; lança GatewayConnectionException em falha
ICubeCompiler.Compile(...)Compila o cubo contra um ou mais relatórios
ICubeCompilerObserverRecebe o stream do resultado, um por relatório compilado

6Autenticação

Quando o Gateway exige autenticação, basta passar um IGatewayAuthenticator ao CubeCompilerFactory. A implementação pronta UserAuthenticator resolve um fluxo OAuth2 de usuário/senha e o token é reaproveitado e renovado automaticamente entre chamadas.

UserAuthenticator

autenticação por usuário/senha
DataAnalyticsDependencyInjectionExtensions.cs
var authenticator = new UserAuthenticator(
    authenticationEndpoint: new Uri("https://seu-identity-server/connect/token"),
    username: "usuario",
    password: "senha",
    organizationId: "org-id");

var compilerFactory = new CubeCompilerFactory(
    "https://seu-gateway/gateway/cubecompiler",
    authenticator);
Uma falha de autenticação lança GatewayAuthenticationException. Para outros esquemas (ex.: um token de serviço pré-emitido), basta implementar sua própria classe : IGatewayAuthenticator — a interface expõe um único método, Task<IGatewayAuthenticationResult> Authenticate(CancellationToken).

7Filtros

FilterBuilder compõe um filtro no nível do relatório/cubo já compilado — útil quando o cubo precisa ser reaproveitado com filtros diferentes sem reconstruir a consulta SQL de origem.

FilterBuilder

condição estruturada + expressão bruta
FilterBuilder.cs
IFilter filter = new FilterBuilder()
    .AddConditional("Uf", "=", "SP")
    .Expression("IdCliente in (1,2,3)", "sql")
    .Build();

IPivotReport report = new PivotReportBuilder()
    .Id("clientesFiltrados")
    .Name("Clientes")
    .AddRow("Nome")
    .AddMeasure("Count")
    .FilterConfiguration(filter)
    .Build();
As duas formas coexistem: AddConditional(campo, operador, valor) — operador como string livre ("=", ">", ...) — e Expression(texto, tipo) para uma expressão bruta adicional. Ambas podem ser combinadas no mesmo IFilter.

8Catálogo de tipos de gráfico

PivotReportBuilder.ChartType(string) é uma string livre — o valor é interpretado pelo Gateway, não validado em tempo de compilação. Abaixo, os 7 valores comprovados em uso real, seguidos pela configuração completa disponível via PlotOptions para outros tipos de série que a biblioteca já modela, mas que não foram observados como ChartType — vale testar de ponta a ponta antes de assumir que o Gateway os renderiza.

✅ Comprovados em uso real

⚠️ Configuração disponível via PlotOptions — não confirmada como ChartType

Pronto para integrar

Instale o pacote NuGet e comece a descrever cubos, relatórios e gráficos com a mesma API fluente.

Voltar para a visão geral