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.
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 filtrousing 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éricoICubeSchema 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();
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 SQLAddCount / AddSum / AddAverageAtalhos para as medidas mais comunsAddMin / AddMax / AddFirstValueOutros atalhos de medida disponíveisAddMeasure(name, type, ...)Forma genérica — qualquer CubeMeasureType, incl. expressões customizadasAddCondition(expression)Filtro aplicado na compilação do cubofilterMap / labelMapTradução de valor bruto ↔ rótulo de exibição, nos dois sentidos2Relató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")IPivotReport totalClientes = new PivotReportBuilder()
.Id("quantidadeClientes")
.Name("Clientes")
.AddMeasure("Count")
.ChartType("singleValue")
.Build();
Percentual em barra empilhada horizontal
Percentage + JavaScriptNumberFormatIPivotReport 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 linhaIPivotReport 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 labelsIPivotReport 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 customizadaIPivotReport 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();
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 hierarquiaAddMeasure(m => ...)Nome, formato, percentual, heatmap, diferença, total acumuladoExpandCollapse(bool)Habilita expansão/recolhimento interativo de hierarquiasOrderBy(o => ...)Ordena por rótulo de dimensão ou por valor de medidaChartType / Chart(...)Tipo de gráfico e configuração visual completa (eixos, legenda, cores, toolbar...)JavaScriptNumberFormatFormatação numérica por medida, avaliada no cliente3Relató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 linhasITableReport 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 + AddOrderByITableReport 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 tabularAddOrderBy / ClearOrderByOrdenação das linhas por coluna4Descrevendo 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-processamentoISourceDatabase 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 cuboAddJoin(joinSql, campos)Anexa um fragmento SQL de join e os campos que ele expõeReadMaxIterations(int)Limite de leitura em lotes da fonte de dados5Conectando 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// 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ãoCubeCompilerFactory.Create(...)Abre a conexão SignalR; lança GatewayConnectionException em falhaICubeCompiler.Compile(...)Compila o cubo contra um ou mais relatóriosICubeCompilerObserverRecebe o stream do resultado, um por relatório compilado6Autenticaçã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/senhavar 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);
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 brutaIFilter 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();
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
Indicador único ChartType
KPI de valor único — a forma mais usada de todas.
.ChartType("singleValue")
Barras ChartType
Comparação de categorias, orientação vertical.
.ChartType("bar")
Barras horizontais ChartType
Comparação de categorias, orientação horizontal.
.ChartType("horizontalBar")
Barras empilhadas horizontais ChartType
Distribuição percentual por categoria (com Percentage).
.ChartType("horizontalStackedBar")
Linha ChartType
Série temporal / tendência ao longo de um eixo (ex.: meses).
.ChartType("line")
Pizza ChartType
Composição/participação de poucas categorias.
.ChartType("pie")
Mapa ChartType
Distribuição geográfica — linhas com dimensões de latitude/longitude.
.AddRow("Latitude").AddRow("Longitude")
.ChartType("map")
⚠️ Configuração disponível via PlotOptions — não confirmada como ChartType
Área PlotOptions
Variante preenchida da linha.
.PlotOptions(p => p.Area(a => a.FillTo("origin")))
Funil PlotOptions
Etapas de um processo/funil de conversão.
.PlotOptions(p => p.Funnel(f => f
.Shape("trapezoid")))
Heatmap PlotOptions
Intensidade de valor por célula (distinto do Heatmap de medida, seção 2).
.PlotOptions(p => p.Heatmap(h => h
.EnableShades(true)
.ShadeIntensity(0.5)))
Candlestick PlotOptions
Abertura/máxima/mínima/fechamento (séries financeiras).
.PlotOptions(p => p.Candlestick(c => c
.Colors(cc => cc.Upward("#00B746").Downward("#EF403C"))))
BoxPlot PlotOptions
Distribuição estatística (quartis, mediana, outliers).
.PlotOptions(p => p.BoxPlot(b => b
.Colors(c => c.Upper("#3B82F6").Lower("#EF4444"))))
Bolhas (Bubble) PlotOptions
Terceira dimensão de valor representada pelo raio do ponto.
.PlotOptions(p => p.Bubble(b => b
.MinBubbleRadius(4).MaxBubbleRadius(24)))
Dispersão (Scatter) PlotOptions
Correlação entre duas medidas, ponto a ponto.
.PlotOptions(p => p.Scatter(s => s
.Jitter(j => j.Enabled(true))))
Donut PlotOptions
Variante da pizza com centro vazado (configurado dentro de Pie).
.ChartType("pie")
.PlotOptions(p => p.Pie(pie => pie.Donut(d => d.Size("65%"))))
Radar PlotOptions
Comparação multivariável em eixos radiais.
.PlotOptions(p => p.Radar(r => r
.Polygons(pg => pg.StrokeColors(new[] { "#4f46e5" }))))
RadialBar (gauge) PlotOptions
Indicador circular de progresso/meta.
.PlotOptions(p => p.RadialBar(r => r
.Hollow(h => h.Size("60%"))))
Treemap PlotOptions
Proporção hierárquica por área de retângulos.
.PlotOptions(p => p.Treemap(t => t
.EnableShades(true).BorderRadius(4)))
Sunburst PlotOptions
Proporção hierárquica em anéis concêntricos.
.PlotOptions(p => p.Sunburst(s => s
.InnerSize(0.3)))
PolarArea PlotOptions
Variante polar da pizza, com raio proporcional ao valor.
.PlotOptions(p => p.PolarArea(pa => pa
.Rings(r => r.StrokeWidth(1))))
Violin PlotOptions
Distribuição estatística com densidade (variante do BoxPlot).
.PlotOptions(p => p.Violin(v => v
.Normalize(true)))
Unit (pictograma) PlotOptions
Cada unidade de valor representada por um ícone repetido.
.PlotOptions(p => p.Unit(u => u
.Shape("circle").UnitValue(100)))
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