2017-10-17 8 views
0

J'ai une table HTML qui sert de fournisseur de données pour le graphique. La table peut être éditée dynamiquement avec un clic du bouton (je peux lui ajouter une nouvelle rangée).(amCharts) Le graphique obtient ses données à partir d'un tableau HTML. Comment mettre à jour la légende si une nouvelle ligne de table est ajoutée dynamiquement?

Je peux mettre à jour le graphique chaque fois qu'une nouvelle ligne est ajoutée. Cependant la légende reste la même, elle n'a que trois graphes initiaux. Comment puis-je mettre à jour la légende à côté du graphique?

Voici mon violon: https://jsfiddle.net/yvzj8acd/2/

Et voici le JS où j'ajouter une nouvelle ligne à la table:

  ////////////////////////////////// 
      // This is where I update the chart 
      ////////////////////////////////// 

      $(document).ready(function() { 

      var newtr = "<tr class='row1a'><th>Row 4</th><td>10000</td><td>20000</td><td>5000</td><td>15000</td><td>7500</td><td>10000</td></tr>" 
      var newtr2 = "<tr class='row1a'><th>Row 5</th><td>15000</td><td>30000</td><td>2000</td><td>10000</td><td>15500</td><td>7000</td></tr>" 
      var newtr3 = "<tr class='row1a'><th>Row 6</th><td>1000</td><td>25000</td><td>15000</td><td>7000</td><td>10000</td><td>8000</td></tr>" 

       $(".ganti").click(function(e) { 
       $('#dataTable').append(newtr, newtr2, newtr3); 

       generateChartData(); 
       chart.dataProvider = chartData; 
       chart.validateData(); 
       chart.animateAgain(); 

       e.preventDefault(); 
       }); 
      }); 

Répondre

1

rapide Pour votre information, AmCharts.ready est équivalent à $(document).ready, de sorte que vous pouvez facilement combiner les deux. En ce qui concerne votre question, vous devez modifier votre approche de génération de données et de graphiques afin qu'elle puisse gérer les données ajoutées dynamiquement. À l'heure actuelle, votre configuration est assez codée en dur sur les trois premières lignes et les nouvelles données ne sont jamais ajoutées. Vous devez également mettre à jour le graphique et ajouter des graphiques supplémentaires au besoin lorsque de nouvelles lignes sont ajoutées.

La première chose que j'ai été mise à jour de votre générer méthode de données pour tirer dynamiquement toutes les lignes qui contiennent des données, plutôt que la méthode hardcoded actuelle qui saisit les trois premières lignes:

function generateChartData() { 

    // initialize empty array 
    chartData = []; 

    // get the table 
    var table = document.getElementById('dataTable'); 

    var years = table.rows[0].getElementsByTagName('th'); 

    //get the rows with graph values. Since data rows always 
    //have a class that begin with "row", use that as the query selector 
    var rows = document.querySelectorAll("tr[class^='row']"); 

    var row; 

    // iterate through the <td> elements of the first row 
    // and construct chart data out of other rows as well 
    for (var x = 0; x < years.length; x++) { 
    //set up the initial object containing the year 
    var dataElem = { 
     "year": years[x].textContent 
    }; 
    //iterate through the other rows based on the current year column (x + 1) and add that value to the 
    //object 
    for (row = 0; row < rows.length; row++) { 
     dataElem[rows[row].cells[0].textContent] = rows[row].cells[x + 1].textContent 
    } 
    //append final object to chart data array 
    chartData.push(dataElem); 
    } 
} 

Ensuite, j'ai créé un generateGraphsFromData méthode qui prend l'instance de graphique et le tableau chartData. Cette méthode compare les champs valueFields trouvés dans le premier élément du tableau chartData et les champs valueFields dans le tableau graphs du graphique et crée de nouveaux graphiques là où il n'y en a aucun dans le tableau. Cela fonctionne à la fois la création graphique et mise à jour:

//update the chart's graphs array based on the the currently known valueFields 
function generateGraphsFromData(chart, chartData) { 
    //get the chart graph value fields 
    var graphValueFields = chart.graphs.map(function(graph) { 
    return graph.valueField; 
    }); 
    //create an array of new graph value fields by filtering out the categoryField 
    //and the currently known valueFields. 
    var newGraphValueFields = Object.keys(chartData[0]).filter(function(key) { 
    return key != chart.categoryField; 
    }).filter(function(valueField) { 
    return graphValueFields.indexOf(valueField) === -1; 
    }); 

    //for each new value field left over, create a graph object and add to the chart. 
    newGraphValueFields.forEach(function(valueField) { 
    var graph = new AmCharts.AmGraph(); 
    graph.title = valueField; 
    graph.valueField = valueField; 
    graph.balloonText = "Rp[[value]]"; 
    graph.lineAlpha = 1; 
    graph.bullet = "round"; 
    graph.stackable = false; // disable stacking 
    chart.addGraph(graph); 
    }); 
} 

À partir de là que je viens mis à jour votre méthode prêt à appeler cette fonction au lieu de définir les graphiques manuellement, ainsi que forcer les deux premiers à cacher:

// Create graphs 
    generateGraphsFromData(chart, chartData); 

    //default the other two graphs to hidden 
    chart.graphs[1].hidden = true; 
    chart.graphs[2].hidden = true; 

Je modifié votre événement de clic pour appeler la méthode generateGraphs ainsi:

$(".ganti").click(function(e) { 
    $('#dataTable').append(newtr, newtr2, newtr3); 

    generateChartData(); 
    generateGraphsFromData(chart, chartData); 
    // ... 

Updated fiddle. J'ai également déplacé la méthode AmCharts.ready dans une fonction autonome séparée et l'ai appelée dans $(document).ready, puisque les deux sont identiques de toute façon. N'hésitez pas à modifier la logique si vous voulez par défaut d'autres nouveaux graphiques cachés ou autres.

+0

Fantastique. Explication approfondie aussi. Merci beaucoup! Une question cependant, si nous combinons le 'AmCharts.ready' à' $ (document) .ready', comment pourrions-nous implémenter des choses comme changer le thème amCharts? Par exemple. Habituellement, nous pouvons utiliser 'AmCharts.theme = AmCharts.themes.patterns;', où devrait-il être placé maintenant? – deathlock

+0

'AmCharts' est une variable globale, vous pouvez donc la définir n'importe où avant la création du graphique. Si vous modifiez un thème dynamiquement, vous devez d'abord effacer les instances de graphique et les recréer. Modifier le thème nécessiterait l'accès aux instances de graphique en dehors de la méthode prête. – xorspark

+1

Voir [cet article sur l'utilisation des thèmes] (https://www.amcharts.com/kbase/working-with-themes/) ainsi que leur exemple de [comment changer les thèmes à l'exécution] (http: // extra .amcharts.com/tutorials/themes/#) – xorspark