AmCharts removing columns from dataProvider with validateData() not working

ε祈祈猫儿з 提交于 2019-12-14 04:06:04

问题


I recently asked about a way to hide columns in AmCharts using hide/show buttons, and it worked pretty well. However, I am now separating functions into different files to create a more dynamic web application.

The page peptide.html holds mostly HTML code, and refers to displayAmCharts.js for the displaying of the AmChart and to any file, in this case 1A80_HUMAN_R_QDAYDGK_D.js, in the data/peptide folder to dynamically load data from. Loading and displaying the data in the AmChart is working fine, however when trying to emplement the hide/show function I get into errors with AmChart.

Every time the function hideValue() is called, a new dataProvider is generated and the old gets replaced the results in the AmChart are just BLANK. Try it yourself in this JS Bin example, show some of the data, select a column to hide, click hide and you'll see that the outlining of the chart stays almost the same, the legend still shows the same selection but there is actual data being displayed.

The strange thing is there commentary code in displayAmCharts() works to replace the values, but when these aren't hard-coded the replacement doesn't work. Some logs to the control of what exactly additionalData contained showed nothing out of the ordinary, i.e. the same structure of data as in the default dataProvider.

Any clues on why the data isn't being shown correctly?

Code below can also be found on JS Bin:

<html>
  <head>
    <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
    <script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
    <script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
    <script src="https://www.amcharts.com/lib/3/serial.js"></script>
    <script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
  </head>   
<script>
  // Source would be C:/Users/Username/Documents/Visualisation Tool/data/peptide/1A80_HUMAN_R_QDAYDGK_D.js
  var graphValues = [{
    "balloonText": "Control: [[value]]",
    "fillAlphas": 1,
    "id": "Control",
    "lineAlpha": 1,
    "lineColor": "#008000",
    "title": "Control",
    "type": "column",
    "newStack": true,
    "valueField": "Control",
    "hidden": true},
{
    "balloonText": "Control SD: [[value]]",
    "fillAlphas": 1,
    "id": "Control SD",
    "lineAlpha": 1,
    "lineColor": "#000000",
    "title": "Control SD",
    "type": "column",
    "valueField": "Control SD",
    "hidden": true},
{
    "balloonText": "Sample A: [[value]]",
    "fillAlphas": 1,
    "id": "Sample A",
    "lineAlpha": 1,
    "lineColor": "#008080",
    "title": "Sample A",
    "type": "column",
    "newStack": true,
    "valueField": "Sample A",
    "hidden": true},
{
    "balloonText": "Sample A SD: [[value]]",
    "fillAlphas": 1,
    "id": "Sample A SD",
    "lineAlpha": 1,
    "lineColor": "#000000",
    "title": "Sample A SD",
    "type": "column",
    "valueField": "Sample A SD",
    "hidden": true},
{
    "title": "All",
    "id": "all",
    "legendValueText": "",
    "legendPeriodValueText": "",
    "hidden": true
}];
var dataValues = [{
    "glycan": "Hex5HexNAc4NeuAc1",
    "Control": 100.0,
    "Control SD": 10.0,
    "Sample A": 80.0,
    "Sample A SD": 8.0},
    {
    "glycan": "Hex5HexNAc4NeuAc2",
    "Control": 50.0,
    "Control SD": 10.0,
    "Sample A": 4.0,
    "Sample A SD": 4.0}
    ];
</script>
  <script>
    // Source would be C:/Users/Username/Documents/Visualisation Tool/scripts/displayAmCharts.js
    var hiddenValues = [];
    var dataProviderVals;

    function displayAmCharts(additionalData){
      var graphsVals = graphValues;
      dataProviderVals = dataValues;
      var chart = AmCharts.makeChart("chartdiv", {
        "type": "serial",
        "dataProvider": dataProviderVals,
        "legend": {
          "useGraphSettings": true,
          "borderAlpha": 1,
          "align": "center",
          "spacing":  125,
          "listeners": [ {
            "event": "hideItem",
            "method": legendHandler
          }, {
            "event": "showItem",
            "method": legendHandler
          }]
        },
        "categoryField": "glycan",
        "categoryAxis": {
          "autoWrap": true
        },
        "rotate": false,
        "graphs": graphsVals,
        "valueAxes": [
          {
            "stackType": "regular",
            "id": "ValueAxis-1",
            "position": "left",
            "axisAlpha": 1
          }
        ],
        "export": {
          "enabled": true
        }
      });   

      /*
      This manual code below works to replace the data.

      var test = [{
        "glycan": "Hex5HexNAc4NeuAc3",
        "Control": 100.0,
        "Control SD": 10.0,
        "Sample A": 80.0,
        "Sample A SD": 8.0},
        {
        "glycan": "Hex5HexNAc4NeuAc4",
        "Control": 50.0,
        "Control SD": 10.0,
        "Sample A": 4.0,
        "Sample A SD": 4.0}
        ];
      chart.dataProvider = test;
      chart.validateData();
      */

      if(additionalData != undefined){
        // Replace the dataProvider with additionalData from hideValue and redraw the chart.
        chart.dataProvider = additionalData;
        chart.validateData();
      }
      function legendHandler(evt) {
        var state = evt.dataItem.hidden;
        if (evt.dataItem.id == "all") {
          for (var i1 in evt.chart.graphs) {
            if (evt.chart.graphs[ i1 ].id != "all") {
              evt.chart[evt.dataItem.hidden ? "hideGraph" : "showGraph" ]( evt.chart.graphs[ i1 ]);
            }
          }
        }
      }
    }
    function hideValue(){
      var selection = document.getElementById("selection");
      var selectedValue = selection.options[selection.selectedIndex].value;
      hiddenValues.push(selectedValue);
      var newDataProvider = [];
      dataValues.forEach(function(item){
        if(hiddenValues.includes(item.glycan) == false){
          newDataProvider.push(item);
        }
      });
      displayAmCharts(newDataProvider);
    }

    function fillSelection(){
      var select = document.getElementById("selection");
      var options = [];
      dataProviderVals.forEach(function(item){
        options.push(item.glycan);
      });
      for(var i = 0; i < options.length; i++) {
        var opt = options[i];
        var el = document.createElement("option");
        el.textContent = opt;
        el.value = opt;
        select.appendChild(el);
      } 
    }
  </script>

    <body onload="displayAmCharts(); fillSelection()">
        <header>
            <h1><b>Visualisation Tool<b></h1>
        </header>
        <h2></h2>
        <div id="chartdiv"><p>Unfortunately there is no data available.</p></div>

        <div>
            <select class="select" id="selection">
                <option disabled selected>Select an option.</option>
            </select>
            <button class="button" type="button" onclick="hideValue()">Hide</button>
            <button class="button" type="button">Show</button>
        </div>
    </body>
    <script type="text/javascript">
        // Commentary in this version as all JS scripts are included in the same page.
        // Open .JS file that contains data at C > Users > User > Documents > Tool folder > Data > Peptide > peptide based on value stored in localStorage, example would be localStorage.getItem("peptideSelection") = "1A80_HUMAN_R_QDAYDGK_D".
        // var peptide = localStorage.getItem("peptideSelection");
        // var JSLink = "C://Users//Z678187//Documents//StackExample//data//peptide//"+peptide+".js";
        // C://Users/Z678187//Documents/StackExample//data//peptide//1A80_HUMAN_R_QDAYDGK_D.js would be the file location.
        // var JSElement = document.createElement('script');
        // JSElement.src = JSLink;
        // JSElement.onload = OnceLoaded;
        // document.getElementsByTagName('head')[0].appendChild(JSElement);
        // function OnceLoaded() {
        //  displayAmCharts();
        //  fillSelection();
        // }
    </script>
</html>    

回答1:


This probably has to do with recreating the chart every time displayAmCharts is called. It is unneccessary and will get amCharts confused. I would define chart as a global variable and only create the chart once.

Your globals

var hiddenValues = [];
var dataProviderVals;
var chart = null; // chart as global variable

displayAmCharts function

function displayAmCharts(additionalData){

  var graphsVals = graphValues;
  dataProviderVals = dataValues;

  // create chart only once
  if(chart == null){

    chart = AmCharts.makeChart("chartdiv", {
      "type": "serial",
      "dataProvider": dataProviderVals,
      // ...
    });

  }

  if(additionalData != undefined){
    // Replace the dataProvider with additionalData from hideValue and redraw the chart.
    chart.dataProvider = additionalData;
    chart.validateData();
  }

  // ...

}

That should solve the issue :-)



来源:https://stackoverflow.com/questions/46522892/amcharts-removing-columns-from-dataprovider-with-validatedata-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!