问题
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