AmCharts 从 dataProvider 中删除列,validateData() 不起作用
AmCharts removing columns from dataProvider with validateData() not working
我最近询问了一个使用 hide/show 按钮的 ,它运行良好。但是,我现在将函数分离到不同的文件中以创建一个更加动态的 Web 应用程序。
页面 peptide.html 主要包含 HTML 代码,参考 displayAmCharts.js显示 AmChart 和任何文件,在本例中为 1A80_HUMAN_R_QDAYDGK_D.js,在 data/peptide 文件夹中动态加载数据。在 AmChart 中加载和显示数据工作正常,但是在尝试实现 hide/show 函数时我遇到了 AmChart 错误。
每次调用函数 hideValue() 时,都会生成一个新的 dataProvider 并替换旧的 AmChart 中的结果只是 BLANK。在这个 JS Bin example 中自己尝试,显示一些数据,select 隐藏一列,单击隐藏,您会看到图表的轮廓几乎保持不变,图例仍然显示相同 selection 但显示的是实际数据。
奇怪的是 displayAmCharts() 中的注释代码可以替换值,但是当这些不是硬编码时,替换不起作用。一些控制 additionalData 包含的内容的日志没有显示任何异常,即与默认 dataProvider 中的数据结构相同。
关于为什么数据未正确显示的任何线索?
以下代码也可以在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>
这可能与每次调用 displayAmCharts
时重新创建图表有关。这是不必要的,会使 amCharts 混淆。我会将 chart
定义为全局变量,并且只创建一次图表。
你的全局变量
var hiddenValues = [];
var dataProviderVals;
var chart = null; // chart as global variable
displayAmCharts 函数
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();
}
// ...
}
这应该可以解决问题:-)
我最近询问了一个使用 hide/show 按钮的
页面 peptide.html 主要包含 HTML 代码,参考 displayAmCharts.js显示 AmChart 和任何文件,在本例中为 1A80_HUMAN_R_QDAYDGK_D.js,在 data/peptide 文件夹中动态加载数据。在 AmChart 中加载和显示数据工作正常,但是在尝试实现 hide/show 函数时我遇到了 AmChart 错误。
每次调用函数 hideValue() 时,都会生成一个新的 dataProvider 并替换旧的 AmChart 中的结果只是 BLANK。在这个 JS Bin example 中自己尝试,显示一些数据,select 隐藏一列,单击隐藏,您会看到图表的轮廓几乎保持不变,图例仍然显示相同 selection 但显示的是实际数据。
奇怪的是 displayAmCharts() 中的注释代码可以替换值,但是当这些不是硬编码时,替换不起作用。一些控制 additionalData 包含的内容的日志没有显示任何异常,即与默认 dataProvider 中的数据结构相同。
关于为什么数据未正确显示的任何线索?
以下代码也可以在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>
这可能与每次调用 displayAmCharts
时重新创建图表有关。这是不必要的,会使 amCharts 混淆。我会将 chart
定义为全局变量,并且只创建一次图表。
你的全局变量
var hiddenValues = [];
var dataProviderVals;
var chart = null; // chart as global variable
displayAmCharts 函数
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();
}
// ...
}
这应该可以解决问题:-)