Jarciano
Jarciano

Reputation: 53

Chart.js Stacked Group Bar model after updating version Chart.js 2.9.4 -> Chart.js 3.5.0

I use Primefaces together with Chart.js in the last update they migrated from Chart.js 2.9.4 to Chart.js 3.5.0

And with that, the graphic model that I used was not configured, see the 2 small videos of the before and after.

See how my chart was and after update it bug

Before https://www.loom.com/share/ca3919221a154f0d9cf9bbe41843cf2b

After https://www.loom.com/share/e9c0ac3e7df942a7aac74a19deb49c6a

If you prefer, here in the Primefaces forum I opened a call, and in it I show an example of the code.

https://forum.primefaces.org/viewtopic.php?f=98&t=72619

    public void criarGraficoFluxoCaixaMensal() {
            barContasReceberPagarAnual = new BarChartModel();
            ChartData data = new ChartData();
    
            LineChartDataSet dataBalancoPrevisto = new LineChartDataSet();
            List<Object> balancoPrevisto = new ArrayList<Object>();
            LineChartDataSet dataBalancoRealizado = new LineChartDataSet();
            List<Object> balancoRealizado = new ArrayList<Object>();
    
            BarChartDataSet barDataReceitaPrevista = new BarChartDataSet();
            barDataReceitaPrevista.setLabel("Recebimentos previstos");
            barDataReceitaPrevista.setBackgroundColor("rgba(102, 187, 106, 0.3)");
            barDataReceitaPrevista.setBorderColor("rgb(102, 187, 106)");
            barDataReceitaPrevista.setStack("principal");
            List<Number> listaContasReceberPrevisto = new ArrayList<Number>();
            List<Object[]> resultReceita = dao.buscarTotalContasReceberAnualPrevisto();
            for (int i = 1; i <= 12; i++) {
             listaContasReceberPrevisto.add(0.0);
                balancoPrevisto.add(0.0);
                balancoRealizado.add(0.0);
    
            }
            for (Object[] result : resultReceita) {
                listaContasReceberPrevisto.add(((int) result[0] - 1), (Number) result[1]);
    
            }
            barDataReceitaPrevista.setData(listaContasReceberPrevisto);
    
            BarChartDataSet barDataDespesaPrevista = new BarChartDataSet();
            barDataDespesaPrevista.setLabel("Pagamentos previstos");
            barDataDespesaPrevista.setBackgroundColor("rgba(239, 83, 80, 0.3)");
            barDataDespesaPrevista.setBorderColor("rgb(239, 83, 80)");
            barDataDespesaPrevista.setStack("principal");
            List<Number> listaContasPagarPrevisto = new ArrayList<Number>();
            List<Object[]> resultsDespesa = dao.buscarTotalContasPagarAnualPrevisto();
    
            for (int i = 1; i <= 12; i++) {
                listaContasPagarPrevisto.add(0.0);
    
            }
            Number in;
            for (Object[] result : resultsDespesa) {
                in = (Number) result[1];
                listaContasPagarPrevisto.add(((int) result[0] - 1), -in.intValue());
    
            }
            barDataDespesaPrevista.setData(listaContasPagarPrevisto);
    
            BarChartDataSet barDataDespesaRealizada = new BarChartDataSet();
            barDataDespesaRealizada.setLabel("Pagamentos realizados");
            barDataDespesaRealizada.setBackgroundColor("rgba(239, 83, 80, 0.6)");
            barDataDespesaRealizada.setBorderColor("rgb(239, 83, 80)");
            barDataDespesaRealizada.setStack("principal");
            List<Number> listaContasPagarRealizada = new ArrayList<Number>();
            List<Object[]> resultsDespesaRealizada = dao.buscarTotalContasPagarAnual();
    
            for (int i = 1; i <= 12; i++) {
                listaContasPagarRealizada.add(0.0);
    
            }
            for (Object[] result : resultsDespesaRealizada) {
                in = (Number) result[1];
                listaContasPagarRealizada.add(((int) result[0] - 1), -in.intValue());
    
            }
            barDataDespesaRealizada.setData(listaContasPagarRealizada);
    
            BarChartDataSet barDataReceitaRealizada = new BarChartDataSet();
            barDataReceitaRealizada.setLabel("Recebimentos realizados");
            barDataReceitaRealizada.setBackgroundColor("rgba(102, 187, 106, 0.6)");
            barDataReceitaRealizada.setBorderColor("rgb(102, 187, 106)");
            barDataReceitaRealizada.setStack("principal");
            List<Number> listaContasReceberRealizada = new ArrayList<Number>();
            List<Object[]> resultsReceberRealizada = dao.buscarTotalContasReceberAnual();
    
            for (int i = 1; i <= 12; i++) {
                listaContasReceberRealizada.add(0.0);
    
            }
            for (Object[] result : resultsReceberRealizada) {
                listaContasReceberRealizada.add(((int) result[0] - 1), (Number) result[1]);
    
            }
            barDataReceitaRealizada.setData(listaContasReceberRealizada);
    
            for (int i = 0; i < 12; i++) {
                try {
                    balancoPrevisto.add(i, listaContasReceberPrevisto.get(i).intValue() - (Math.abs(listaContasPagarPrevisto.get(i).intValue())));
    
                    balancoRealizado.add(i, (listaContasReceberRealizada.get(i).intValue() - (Math.abs(listaContasPagarRealizada.get(i).intValue()))));
                } catch (Exception ex) {
                    balancoPrevisto.add(i, 0);
                    balancoRealizado.add(i, 0);
                }
    
            }
            dataBalancoPrevisto.setData(balancoPrevisto);
            dataBalancoPrevisto.setFill(false);
            dataBalancoPrevisto.setLabel("Saldo previsto");
            dataBalancoPrevisto.setBackgroundColor("rgba(66, 165, 245, 0.3)");
            dataBalancoPrevisto.setBorderColor("rgba(66, 165, 245, 0.3)");
            dataBalancoPrevisto.setTension(0.1);
            dataBalancoRealizado.setData(balancoRealizado);
            dataBalancoRealizado.setFill(false);
            dataBalancoRealizado.setLabel("Saldo realizado");
            dataBalancoRealizado.setBackgroundColor("rgba(66, 165, 245, 0.6)");
            dataBalancoRealizado.setBorderColor("rgb(66, 165, 245)");
            dataBalancoRealizado.setTension(0.1);
            data.addChartDataSet(dataBalancoPrevisto);
            data.addChartDataSet(dataBalancoRealizado);
            data.addChartDataSet(barDataDespesaPrevista);
            data.addChartDataSet(barDataDespesaRealizada);
            data.addChartDataSet(barDataReceitaPrevista);
            data.addChartDataSet(barDataReceitaRealizada);
    
            List<String> labels = new ArrayList<>();
            labels.add("Janeiro");
            labels.add("Fevereiro");
            labels.add("Março");
            labels.add("Abril");
            labels.add("Maio");
            labels.add("Junho");
            labels.add("Julho");
            labels.add("Agosto");
            labels.add("Setembro");
            labels.add("Outubro");
            labels.add("Novembro");
            labels.add("Dezembro");
            data.setLabels(labels);
            barContasReceberPagarAnual.setData(data);
    
            //Options
            /*BarChartOptions options = new BarChartOptions();
            CartesianScales cScales = new CartesianScales();
            CartesianLinearAxes linearAxes = new CartesianLinearAxes();
            linearAxes.setStacked(true);
    
            cScales.addXAxesData(linearAxes);
            cScales.addYAxesData(linearAxes);
            options.setScales(cScales);
    
            Title title = new Title();
            title.setDisplay(true);
            title.setText("Bar Chart - Stacked");
            options.setTitle(title);
    
            Tooltip tooltip = new Tooltip();
            tooltip.setMode("index");
            tooltip.setIntersect(false);
            options.setTooltip(tooltip);*/
            BarChartOptions options = new BarChartOptions();
            CartesianScales cScales = new CartesianScales();
            CartesianLinearAxes linearAxes = new CartesianLinearAxes();
            CartesianLinearTicks ticks = new CartesianLinearTicks();
            ticks.setBeginAtZero(true);
            linearAxes.setTicks(ticks);
    
            cScales.addYAxesData(linearAxes);
            options.setScales(cScales);
    
            Tooltip tooltip = new Tooltip();
            tooltip.setMode("index");
            tooltip.setDisplayColors(true);
            tooltip.setIntersect(true);
            barContasReceberPagarAnual.setOptions(options);
            barContasReceberPagarAnual.setExtender("currencyBr");
        }

The light green is the predicted one and the dark green is the accomplished one, as the forecast bar is being executed, it is hidden by the accomplished one.

enter image description here

See that now what has been accomplished is not overlapping with what was expected.

enter image description here

I tried to test according to your code, but the problem persists.

The problem is in the union of 4 bars starting at the same place, we want to put the 4 bars in a single Stacked.

See that if I change these two lines the bars are side by side

 barDataReceitaPrevista.setStack("principal");
 barDataDespesaPrevista.setStack("principal");
 barDataReceitaRealizada.setStack("principal_1");
 barDataDespesaRealizada.setStack("principal_1");

enter image description here

And when I try to make them start in the same place, it looks like this

 barDataReceitaPrevista.setStack("principal");
 barDataDespesaPrevista.setStack("principal");
 barDataReceitaRealizada.setStack("principal");
 barDataDespesaRealizada.setStack("principal");

enter image description here

Upvotes: 2

Views: 303

Answers (1)

Melloware
Melloware

Reputation: 12019

OK so the problem is you are setting both your axes to stacked:true which will force ChartsJS to "add" the values together. to get them to "overlap" you need to set Y Axes to stacked:false like this..

CartesianLinearAxes xAxes = new CartesianLinearAxes();
xAxes.setStacked(true);
cScales.addXAxesData(xAxes);

CartesianLinearAxes yAxes = new CartesianLinearAxes();
yAxes.setStacked(false);
cScales.addYAxesData(yAxes);

Upvotes: 1

Related Questions