amCharts - Criar link para um outro relatório

Bom dia.

Eu tenho um gráfico que criei com amCharts. Existe alguma maneira de criar um link em que quando eu clico em uma das barras geradas pelo gráfico ele abre uma outra consulta baseado nos dados utilizados pelas mesma.

WITH q1 AS (
    SELECT
    CASE
        WHEN Mes = 1 THEN '1 - Jan'
        WHEN Mes = 2 THEN '2 - Fev'
        WHEN Mes = 3 THEN '3 - Mar'
        WHEN Mes = 4 THEN '4 - Abr'
        WHEN Mes = 5 THEN '5 - Mai'
        WHEN Mes = 6 THEN '6 - Jun'
        WHEN Mes = 7 THEN '7 - Jul'
        WHEN Mes = 8 THEN '8 - Ago'
        WHEN Mes = 9 THEN '9 - Set'
        WHEN Mes = 10 THEN '10 - Out'
        WHEN Mes = 11 THEN '11 - Nov'
        WHEN Mes = 12 THEN '12 - Dez'
    END AS Mes,
    SUM(Total) as Total,
    SUM(COALESCE(Atraso, 0)) as Atraso,
    SUM(COALESCE(Prazo, 0)) as Prazo
    FROM (
        SELECT
        Mes,
        COUNT(cte) as Total,
        CASE WHEN status = 'Atraso' THEN COUNT(cte) END as Atraso,
        CASE WHEN status = 'Prazo' OR status = 'Prazo RespCli' THEN COUNT(cte) END as Prazo
        FROM ltm_performance_entrega
        WHERE dtentrega >= now() - INTERVAL '6 months'
        GROUP BY status, Mes
    ) TAB
    GROUP BY 
    CASE
        WHEN Mes = 1 THEN '1 - Jan'
        WHEN Mes = 2 THEN '2 - Fev'
        WHEN Mes = 3 THEN '3 - Mar'
        WHEN Mes = 4 THEN '4 - Abr'
        WHEN Mes = 5 THEN '5 - Mai'
        WHEN Mes = 6 THEN '6 - Jun'
        WHEN Mes = 7 THEN '7 - Jul'
        WHEN Mes = 8 THEN '8 - Ago'
        WHEN Mes = 9 THEN '9 - Set'
        WHEN Mes = 10 THEN '10 - Out'
        WHEN Mes = 11 THEN '11 - Nov'
        WHEN Mes = 12 THEN '12 - Dez'
    END
),

q_max_total AS (
    SELECT MAX(Total) AS max_total FROM q1
),

q_json AS (
    SELECT '{
        "type": "serial",
        "categoryField": "Mes",
        "startDuration": 1,
        "creditsPosition": "bottom-right",
        "hideCredits": true,
        "categoryAxis": {
            "gridPosition": "start"
        },
        "graphs": [
            {
                "balloonText": "[[title]] em [[Mes]]:[[value]]",
                "fillAlphas": 1,
                "fillColors": "#FF0000",
                "id": "AmGraph-1",
                "title": "Atraso",
                "type": "column",
                "valueField": "Atraso",
                "labelText": "[[value]]"
                
            },
            {
                "balloonText": "[[title]] em [[Mes]]:[[value]]",
                "fillAlphas": 1,
                "fillColors": "#0000FF",
                "id": "AmGraph-2",
                "title": "Prazo",
                "type": "column",
                "valueField": "Prazo",
                "labelText": "[[value]]"
                
            },            
            {
                "balloonText": "[[title]] em [[Mes]]:[[value]]",
                "fillAlphas": 1,
                "fillColors": "#6CE01B",
                "id": "AmGraph-3",
                "title": "Total",
                "type": "column",
                "valueField": "Total",
                "labelText": "[[value]]"
                
            }
        ],
        "valueAxes": [
            {
                "id": "ValueAxis-1",
                "stackType": "none",
                "maximum": ' || (SELECT max_total FROM q_max_total) || ',
                "title": "Total"
            }
        ],
        "legend": {
            "enabled": true,
            "useGraphSettings": true
        },
        "dataProvider": [' ||
        ARRAY_TO_STRING(ARRAY(
            SELECT format('{"Mes": "%s", "Atraso": %s, "Prazo": %s,"Total": %s}', 
                          Mes, COALESCE(Atraso, 0), COALESCE(Prazo, 0), COALESCE(Total, 0))
            FROM q1
        ), ', ') ||
        ']
    }' AS jsondata
)

SELECT 
'<style>
  .amcharts-chart-div > a {
    display: none;
  }
</style>' || E'\r\n'
|| '<div class="drawChart" style="box-sizing:border-box;width:100%;height:310px;">' || E'\r\n'
|| E'\t<script type="application/json">\r\n'
|| jsondata
|| E'\r\n\t</script>\r\n'
|| '</div>'::VARCHAR AS htmlelement

FROM q_json

Boa tarde @JonasKRitter,

Para poder efetuar a adição de um evento que escute o clique em barras do gráfico será necessário adicionar as seguintes chaves na construção do JSON:

"chartCursor": {
    "fullWidth": true,
    "cursorAlpha": 0.1,
    "listeners": [{
      "event": "changed",
      "method": "GetCursorPosition"
    }]
},
"listeners": [{
  "event": "init",
  "method": "InitListener"
}]

Após, adicione este conteúdo. Inclua no arquivo JS que interage com o AmCharts, as seguintes funções:

  • Para capturar onde o cursor está no gráfico:
function GetCursorPosition(ev) {
    ev.chart.lastCursorPosition = ev.index;
}
  • Adicionar o evento para escutar o clique e efetuar uma ação:
function InitListener(ev) {
    jQuery(ev.chart.chartDiv).on('click', function(e) {
        if (!isNaN(ev.chart.lastCursorPosition)) {
            new latromi.windowManager().openWindow({
                window: {
                    title: "Janela",
                    height: 600,
                    width: 800,
                    targetUpgradeCode: "FRM00000030900002420240905165836170305", // Código do formulário LATROMI
                    targetParameters: {
                        mes: {
                            value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Mes
                        },
                        atraso: {
                            value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Atraso
                        },
                        prazo: {
                            value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Prazo
                        },
                        total: {
                            value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Total
                        }
                    },
                    
                },
                options: { 
                    modal: true,
                    maximized: false 
                }
            });
        }
    });
}

Por fim, no retorno do JS adicione:

// Todas as funções acima são "privadas", e não podem ser chamadas externamente.
// As únicas funções que podem ser chamadas externamente são as que compões o resultado a seguir:
return {
    GetCursorPosition: function(e) { GetCursorPosition(e) },
    InitListener: function(e) { InitListener(e) }
}
1 curtida

Bom dia @Diego_Ramos

Eu não se eu que fiz algo de errado. Mas, não funcionou para mim. Não sei se é algo de errado no JS publico ou na composição do JSON. Também estou tendo um problema com event: changed. Se eu adiciono isso no gráfico ele fica travado quando eu passo o mouse no gráfico.

Aqui está o JSON:

WITH q1 AS (
    SELECT
        1 AS Mes, 'Janeiro' AS MesNome, 7.6 AS Previsto, 7.6 AS Realizado
    UNION ALL
    SELECT
        2 AS Mes, 'Fevereiro' AS MesNome, 8.0 AS Previsto, 7.6 AS Realizado
    UNION ALL
    SELECT
        3 AS Mes, 'Março' AS MesNome, 8.9 AS Previsto, 8.9 AS Realizado
    UNION ALL
    SELECT
        4 AS Mes, 'Abril' AS MesNome, 9.6 AS Previsto, 9.6 AS Realizado
    UNION ALL
    SELECT
        5 AS Mes, 'Maio' AS MesNome, 10.4 AS Previsto, 10.5 AS Realizado
    UNION ALL
    SELECT
        6 AS Mes, 'Junho' AS MesNome, 9.5 AS Previsto, 9.5 AS Realizado
    UNION ALL
    SELECT
        7 AS Mes, 'Julho' AS MesNome, 10.6 AS Previsto, 12.4 AS Realizado
    UNION ALL
    SELECT
        8 AS Mes, 'Agosto' AS MesNome, 10.7 AS Previsto, 13.7 AS Realizado
    UNION ALL
    SELECT
        9 AS Mes, 'Setembro' AS MesNome, 12.6 AS Previsto, 11.5 AS Realizado
    UNION ALL
    SELECT
        10 AS Mes, 'Outubro' AS MesNome, 11.3 AS Previsto, 10.2 AS Realizado
    UNION ALL
    SELECT
        11 AS Mes, 'Novembro' AS MesNome, 12.6 AS Previsto, 13.2 AS Realizado
    UNION ALL
    SELECT
        12 AS Mes, 'Dezembro' AS MesNome, 13.5 AS Previsto, 14.8 AS Realizado
),


q2 as (select max(Realizado) as MaxRealizado from q1),


q_json AS (
    SELECT '{
        "type": "serial",
        "categoryField": "MesNome",
        "startDuration": 1,
        "creditsPosition": "bottom-right",
        "hideCredits": true,
        "autoMargins": false,
        "marginTop": 2,
        "marginBottom": 25,
        "marginLeft": 50,
        "thousandsSeparator": ".",
        "categoryAxis": {
            "gridPosition": "start"
        },
        "chartCursor": {
            "fullWidth": true,
            "cursorAlpha": 0.1,
            "listeners": [{
              "event": "changed",
              "method": "GetCursorPosition"
            }]
        },
        "listeners": [{
          "event": "init",
          "method": "InitListener"
        }],
        "graphs": [
            {
                "balloonText": "[[title]] em [[MesNome]]:[[value]]",
                "fillAlphas": 1,
                "fillColors": "#FF8000",
                "id": "AmGraph-1",
                "title": "Previsto",
                "labelAnchor": "start",
                "labelPosition": "left",
                "labelRotation": 270,
                "type": "column",
                "valueField": "Previsto",
                "labelText": "[[value]] Mi"
            },
            {
                "balloonText": "[[title]] em [[MesNome]]:[[value]]",
                "fillAlphas": 1,
                "fillColors": "#00cc00",
                "id": "AmGraph-2",
                "title": "Realizado",
                "labelAnchor": "start",
                "labelPosition": "left",
                "labelRotation": 270,
                "type": "column",
                "valueField": "Realizado",
                "labelText": "[[value]] Mi"
            }
        ],
        "valueAxes": [
            {
                "id": "ValueAxis-1",
                "stackType": "none",
                "autoGridCount": true,
                "maximum": ' || CEIL((SELECT  MaxRealizado FROM q2) * 1.2) || '
            }
        ],
        "legend": {
            "enabled": true,
            "useGraphSettings": true,
            "position": "top",
            "align": "center",
            "fontSize": 10,
            "markerSize": 6
        },
        "dataProvider": [' ||
        ARRAY_TO_STRING(ARRAY(
            SELECT format('{"MesNome": "%s", "Previsto": %s, "Realizado": %s}', 
                          MesNome, COALESCE(Previsto, 0), COALESCE(Realizado, 0))
            FROM q1
        ), ', ') ||
        ']
    }' AS jsondata
)


SELECT 
'<style>
  .amcharts-chart-div > a {
    display: none;
  }
</style>' || E'\r\n'
|| '<div class="drawChart" style="box-sizing:border-box;width:100%;height:350px;">' || E'\r\n'
|| E'\t<script type="application/json">\r\n'
|| jsondata
|| E'\r\n\t</script>\r\n'
|| '</div>'::VARCHAR AS htmlelement

FROM q_json

Aqui está o JS público:

window.addEventListener('load', function () {
    // Faz a configuração do AMCharts
    latromi.extensions.loadScripts(['https://static.latromi.com.br/adapters/amcharts.configurator-1.0.js'], function () {
        // AmCharts: https://www.amcharts.com
        var amChartsConfig = new amChartsConfigurator({
            containerCssClass: 'amcharts-container',    // Classe CSS usada no objeto que utiliza os gráficos
            chartCssClass: 'drawChart',                 // Classe CSS do elemento onde o grafico deve ser montado
            drawInterval: 100                           // Intervalo de verificação dos elementos para refazer os gráficos
        });

        function GetCursorPosition(ev) {
            ev.chart.lastCursorPosition = ev.index;
        }

        function InitListener(ev) {
            jQuery(ev.chart.chartDiv).on('click', function (e) {
                if (!isNaN(ev.chart.lastCursorPosition)) {
                    new latromi.windowManager().openWindow({
                        window: {
                            title: "Janela",
                            height: 600,
                            width: 800,
                            targetUpgradeCode: "CST00000196200065420240916112201930305", // Código do formulário LATROMI
                            targetParameters: {
                                mes: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Mes
                                },
                                atraso: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Atraso
                                },
                                prazo: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Prazo
                                },
                                total: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Total
                                }
                            }
                        },
                        options: {
                            modal: true,
                            maximized: false
                        }
                    });
                }
            });
        }

        // Carrega os gráficos
        amChartsConfig.load();
        
        // Substitua a função de captura da posição do cursor com debounce
        amChartsConfig.onChartDrawn(function (ev) {
            GetCursorPosition(ev);  
            InitListener(ev);
        });
        
        return {
            GetCursorPosition: function(e) { GetCursorPosition(e) },
            InitListener: function(e) { InitListener(e) }
        };
    });

    // Remover o link "JS chart by amCharts" após carregar os gráficos
    setTimeout(function () {
        var amChartsLinks = document.querySelectorAll('.amcharts-chart-div > a');
        amChartsLinks.forEach(function (link) {
            link.parentNode.removeChild(link);
        });
    }, 500);  // Aguarde meio segundo para garantir que os gráficos tenham sido carregados
});

@JonasKRitter Bom dia,

Poderia efetuar a seguinte ação no código JS:

  • Declarar a função anonima dentro do loadScripts em uma variavel externa.
    Exemplo:
    var chartMap = function () {
        // AmCharts: https://www.amcharts.com
        var amChartsConfig = new amChartsConfigurator({
            containerCssClass: 'amcharts-container',    // Classe CSS usada no objeto que utiliza os gráficos
            chartCssClass: 'drawChart',                 // Classe CSS do elemento onde o grafico deve ser montado
            formName: 'chartMap',                         // Indica o nome da variavel que se encontra a configuração do AmCharts
            drawInterval: 100                           // Intervalo de verificação dos elementos para refazer os gráficos
        });
    
        function GetCursorPosition(ev) {
            ev.chart.lastCursorPosition = ev.index;
        }
    
        function InitListener(ev) {
            jQuery(ev.chart.chartDiv).on('click', function (e) {
                if (!isNaN(ev.chart.lastCursorPosition)) {
                    new latromi.windowManager().openWindow({
                        window: {
                            title: "Janela",
                            height: 600,
                            width: 800,
                            targetUpgradeCode: "CST00000196200065420240916112201930305", // Código do formulário LATROMI
                            targetParameters: {
                                mes: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Mes
                                },
                                atraso: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Atraso
                                },
                                prazo: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Prazo
                                },
                                total: {
                                    value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Total
                                }
                            }
                        },
                        options: {
                            modal: true,
                            maximized: false
                        }
                    });
                }
            });
        }
    
        // Carrega os gráficos
        amChartsConfig.load();
        
        // Substitua a função de captura da posição do cursor com debounce
        amChartsConfig.onChartDrawn(function (ev) {
            GetCursorPosition(ev);  
            InitListener(ev);
        });
        
        return {
            GetCursorPosition: function(e) { GetCursorPosition(e) },
            InitListener: function(e) { InitListener(e) }
        };
    }
    
  • Adicionar no ‘amChartsConfigurator’ a propriedade ‘formName’ para indicar o nome da variavel que se encontra a declaração das funções usadas no AmCharts.
    Exemplo:
        // AmCharts: https://www.amcharts.com
        var amChartsConfig = new amChartsConfigurator({
            containerCssClass: 'amcharts-container',    // Classe CSS usada no objeto que utiliza os gráficos
            chartCssClass: 'drawChart',                 // Classe CSS do elemento onde o grafico deve ser montado
            formName: 'chartMap',                         // Indica o nome da variavel que se encontra a configuração do AmCharts
            drawInterval: 100                           // Intervalo de verificação dos elementos para refazer os gráficos
        });
    

Desculpa a ignorância mas onde seria esse loadScripts? E a primeira vez que estou utilizando JS no Latromi então não tenho muita experiência

Bom dia @JonasKRitter,

Pode ficar tranquilo, estou aqui para ajudar.

Na parte do código que tu me passou, na resposta anterior.

  • A parte que marquei em vermelho é indicando o método “LoadScripts”
  • A parte marcada em amarelo é a função anonima, então basicamente seria pegar o que está após a ‘,’ e declarar em uma variável no código e substituir no lugar

1 curtida

Caso seja o mesmo código ainda, você pode substituir pelo seguinte:

var chartMap = function () {
    // AmCharts: https://www.amcharts.com
    var amChartsConfig = new amChartsConfigurator({
        containerCssClass: 'amcharts-container',    // Classe CSS usada no objeto que utiliza os gráficos
        chartCssClass: 'drawChart',                 // Classe CSS do elemento onde o grafico deve ser montado
        formName: 'chartMap',                         // Indica o nome da variavel que se encontra a configuração do AmCharts
        drawInterval: 100                           // Intervalo de verificação dos elementos para refazer os gráficos
    });

    function GetCursorPosition(ev) {
        ev.chart.lastCursorPosition = ev.index;
    }

    function InitListener(ev) {
        jQuery(ev.chart.chartDiv).on('click', function (e) {
            if (!isNaN(ev.chart.lastCursorPosition)) {
                // Código que será disparado quando clicar na série do gráfico
                new latromi.windowManager().openWindow({
                    window: {
                        title: "Janela",
                        height: 600,
                        width: 800,
                        targetUpgradeCode: "CST00000196200065420240916112201930305", // Código do formulário LATROMI
                        targetParameters: {
                            mes: {
                                value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Mes
                            },
                            atraso: {
                                value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Atraso
                            },
                            prazo: {
                                value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Prazo
                            },
                            total: {
                                value: ev.chart.dataProvider[ev.chart.lastCursorPosition].Total
                            }
                        }
                    },
                    options: {
                        modal: true,
                        maximized: false
                    }
                });
            }
        });
    }

    // Carrega os gráficos
    amChartsConfig.load();
    
    // Substitua a função de captura da posição do cursor com debounce
    amChartsConfig.onChartDrawn(function (ev) {
        GetCursorPosition(ev);  
        InitListener(ev);
    });
    
    return {
        GetCursorPosition: function(e) { GetCursorPosition(e) },
        InitListener: function(e) { InitListener(e) }
    };
}

window.addEventListener('load', function () {
    // Faz a configuração do AMCharts
    latromi.extensions.loadScripts(['https://static.latromi.com.br/adapters/amcharts.configurator-1.0.js'], chartMap());

    // Remover o link "JS chart by amCharts" após carregar os gráficos
    setTimeout(function () {
        var amChartsLinks = document.querySelectorAll('.amcharts-chart-div > a');
        amChartsLinks.forEach(function (link) {
            link.parentNode.removeChild(link);
        });
    }, 500);  // Aguarde meio segundo para garantir que os gráficos tenham sido carregados
});

Que já terá as alterações que mencionei acima

1 curtida