javascript - 第二个选项卡不显示图表。有人能看出为什么吗?
问题描述
第一个选项卡正在工作,但其他选项卡只是隐藏了第一个选项卡,但不显示图表。我认为可能存在语法错误。我无法解决这个问题,如果有任何解决方案,我将不胜感激。谢谢你。
$(document).ready(function () {
$.ajax({
url: "http://localhost/callerstats.php" ,
method: "GET",
success: function(data) {
console.log(data);
var OriginationName = [];
var Anzahl = [];
for(var i in data) {
OriginationName.push(data[i].OriginationName);
Anzahl.push(data[i].Anzahl);
}
var chartdata = {
labels: OriginationName,
datasets : [
{
label: 'Top 15 Caller Employee',
backgroundColor: 'rgba(200, 200, 200, 0.75)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Anzahl
}
]
};
var ctx = $("#mycanvas1");
var barGraph = new Chart(ctx, {
type: 'horizontalBar',
data: chartdata
});
$('#tab1').hide();
$('#tab1_btn').on('click', function() {
$('#tab1').show();
$('#tab2').hide();
$('#tab3').hide();
$('#tab4').hide();
$('#tab5').hide();
})
},
error: function(data) {
console.log(data);
}
});
});
$(document).ready(function () {
$.ajax({
url: "http://localhost/calledstats.php" ,
method: "GET",
success: function(data) {
console.log(data);
var DestinationName = [];
var Anzahl = [];
for(var i in data) {
DestinationName.push(data[i].DestinationName);
Anzahl.push(data[i].Anzahl);
}
var chartdata = {
labels: DestinationName,
datasets : [
{
label: 'Top 15 Called Employee',
backgroundColor: 'rgba(200, 200, 200, 0.75)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data: Anzahl
}
]
};
var ctx2 = $("#mycanvas2");
var barGraph2 = new Chart(ctx2, {
type: 'bar',
data: chartdata
});
$('#tab2').hide();
$('#tab2_btn').on('click', function() {
$('#tab1').hide();
$('#tab2').show();
$('#tab3').hide();
$('#tab4').hide();
$('#tab5').hide();
})
},
error: function(data) {
console.log(data);
}
});
});
html - file
<!DOCTYPE html>
<html lang="en">
<head>
<title> Omid Chart </title>
<style type="text/css">
#chart-container1 {
width: 45%;
height: 300px;
display: inline-block;
}
#chart-container2 {
width: 45%;
height: 300px;
display: inline-block;
}
#chart-container3 {
width: 45%;
height: 300px;
display: inline-block;
}
#chart-container4 {
width: 45%;
height: 300px;
display: inline-block;
}
#chart-container5 {
width: 45%;
height: 300px;
display: inline-block;
}
</style>
</head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"</meta>
<button id="tab1_btn">Top 15 Caller Employee</button>
<button id="tab2_btn">Top 15 Called Employee</button>
<button id="tab3_btn">Top Called Filiale</button>
<button id="tab4_btn">Most calls outside of Germany</button>
<button id="tab5_btn">Calls outside of Germany</button>
<div id="tab_cover"> </div>
<div id="tabs">
<div id="tab1" class="tab">
<div id="chart-container1" class="chart_container">
<canvas id="mycanvas1"></canvas>
</div>
<div id="tab2" class="tab">
<div id="chart-container2" class="chart_container">
<canvas id="mycanvas2"></canvas>
</div>
<div id="tab3" class="tab">
<div id="chart-container3" class="chart_container">
<canvas id="mycanvas3"></canvas>
</div>
<div id="tab4" class="tab">
<div id="chart-container4" class="chart_container">
<canvas id="mycanvas4"></canvas>
</div>
<div id="tab5" class="tab">
<div id="chart-container5" class="chart_container">
<canvas id="mycanvas5"></canvas>
</div>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="bar.js"></script>
</body>
</html>
解决方案
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
/*
Ignore the db connection and the specific SQL queries
- these, obviously, are pertinent to my system and not
the real one.
Use own db connection
*/
set_include_path('c:/wwwroot/dbo/');
require 'db-conn-details.php';
$dbname='movies';
require 'mysqli-conn.php';
/*
To emulate how one MIGHT use a single script to serve ALL
chart data simply by using a parameter in the AJAX request.
Use own SQL queries to query for each button click
$_POST['chart'] is sent by the ajax request and uses the
dataset attribute `id` -> `data-id=1` etc
I used a db of movies to supply suitable data to populate
various charts - the data does not bear any resemblance to
whatever datasets you are using.
*/
switch( intval( $_POST['chart'] ) ){
case 1:$sql='select `title`,`rating` from `vwmovies` where `year`=1970 and `rating` > 0 limit 10';break;
case 2:$sql='select `title`,`rating` from `vwmovies` where `year`=1980 and `rating` > 0 limit 10';break;
case 3:$sql='select `title`,`rating` from `vwmovies` where `year`=1993 and `rating` > 0 limit 10';break;
case 4:$sql='select `title`,`rating` from `vwmovies` where `year`=2005 and `rating` > 0 limit 10';break;
case 5:$sql='select `title`,`rating` from `vwmovies` where `year`=2015 and `rating` > 0 limit 10';break;
}
$res=$db->query( $sql );
$tmp=[];
while( $rs=$res->fetch_object()){
$tmp[]=[
'name' => $rs->title,
'rating' => $rs->rating
];
}
exit( json_encode( $tmp ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Omid Charts</title>
<style>
:root{
--ptop:0;
--pleft:0;
}
body *{
font-family:monospace;
}
div{
margin:1rem;
}
#tabs{
height:calc( 500px + 4rem );
}
#tabs > div {
border:1px solid black;
background:whitesmoke;
display:none;
}
#tabs > div > div{
width: 75%;
height: 500px;
display: inline-block;
}
canvas{
margin:auto;
float:none;
}
.visible{
display:block!important;
}
.visible:before{/* red rectangle, top left (TL) */
position:absolute;
top:var(--ptop);
left:var(--pleft);
content:'Chart 'attr(data-id)': 'attr(data-label);
padding:0.5rem 1rem;
background:red;
color:white;
border-right:1px solid black;
border-bottom:1px solid black;
border-top:1px solid black;
}
button{
padding:0.5rem;
}
</style>
<script src='//canvasjs.com/assets/script/canvasjs.min.js'></script>
<script src='//cdn.jsdelivr.net/npm/chart.js@2.8.0'></script>
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js'></script>
<script>
document.addEventListener('DOMContentLoaded',function(){
/* The container for the chart tabs */
let box=document.getElementById('tabs').getBoundingClientRect();
/* modify the :root variables to aid positioning of chart identifier ( red-rectangle, TL ) */
let root=document.documentElement;
root.style.setProperty( '--ptop', box.top+'px' );
root.style.setProperty( '--pleft', 'calc( '+box.left+' + 1rem )px' );
/* The url to send ajax requests to */
/*
Rather than separate scripts to handle the request
a single script could be used but use a parameter
in the request to determine which SQL query to run.
See above PHP code...
*/
const URL=location.href;
/* The method used for the AJAX request */
const METHOD='post';
/* className assigned to a DIV/panel to ensure it is visible */
const VIZ='visible';
/* utility to find all chart containers and hide them and then reveal specific chart */
const showhidetabs=function(n){
Array.from( document.querySelectorAll( '#tabs > div' ) ).forEach( div=>{
if( div.classList.contains( VIZ ) )div.classList.remove( VIZ )
});
n.classList.add( VIZ );
};
/* chart builder */
const buildchart=function( canvas, label ){
let ctxt=canvas.getContext('2d');
let div=canvas.parentNode.parentNode;
let id=div.dataset.id;
/* issue query to PHP server */
/* return JSON format data */
$.ajax({
url:URL,
method:METHOD,
data:{
task:'fetch-data',
label:label,
chart:id
},
success:function( data ){
let json=JSON.parse( data );
let labels=[];
let results=[];
if( !div.hasAttribute('data-label') ){
div.dataset.label=label;
}
json.forEach( obj=>{ // names as per column names in db query results
labels.push( obj.name );
results.push( obj.rating );
});
let chartdata = {
labels:labels,
datasets:[
{
label:label,
backgroundColor: 'rgba(200, 200, 200, 0.75)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(200, 200, 200, 1)',
hoverBorderColor: 'rgba(200, 200, 200, 1)',
data:results
}
]
};
let barGraph=new Chart( ctxt, {
type:'horizontalBar',
data:chartdata
});
},
error:function( err ){
console.info( err )
}
});
};
/* click event handler that hides other charts and fetches data to build new chart */
const bttnclickhandler=function(e){
// find the chart container
let div=document.querySelector('#tabs > div[ data-id="'+this.dataset.id+'" ]');
// find the canvas
let canvas=div.querySelector('canvas');
// find the button text - to be used in the chart as the label
let label=this.innerHTML;
// call the methods above.
showhidetabs.call( this, div );
buildchart.call( this, canvas, label );
};
/* assign event handler to each button */
Array.from( document.querySelectorAll( '#content > button' ) ).forEach( bttn=>{
bttn.addEventListener('click', bttnclickhandler )
})
});
</script>
</head>
<body>
<!--
The HTML markup is basically the same as per the question except that
it now validates correctly as it is properly nested - which I believe
caused many issues in the original.
It has been simplified but retains sufficient attributes to allow
easy targeting via Javascript and also styling via CSS without
unneccessary "bloat"
-->
<div id='content'>
<button data-id=1>Top 15 Caller Employee</button>
<button data-id=2>Top 15 Called Employee</button>
<button data-id=3>Top Called Filiale</button>
<button data-id=4>Most calls outside of Germany</button>
<button data-id=5>Calls outside of Germany</button>
<!-- what does this do? -->
<div id='cover'></div>
<!--
The `data-id` attributes are used by AJAX function
to help determine which SQL query to run.
-->
<div id='tabs'>
<div data-id='1'>
<div>
<canvas></canvas>
</div>
</div>
<div data-id='2'>
<div>
<canvas></canvas>
</div>
</div>
<div data-id='3'>
<div>
<canvas></canvas>
</div>
</div>
<div data-id='4'>
<div>
<canvas></canvas>
</div>
</div>
<div data-id='5'>
<div>
<canvas></canvas>
</div>
</div>
</div>
</div>
</body>
</html>
推荐阅读
- android - osmdroid - 标记的自定义视图
- java - MultipleBagFetchException - 如果我们只有一个集合怎么办
- python - 为什么剪枝中的参数会在 tensorflow 的 tfmot 中增加
- .net - 如何在 Visual Studio 2019 上解锁 NLog.config
- c++ - C++17 新功能:错误 C4996:'getenv':此函数或变量可能不安全。考虑改用 _dupenv_s
- javascript - 除非先进入根域,否则 React Router 无法呈现确切的路径
- postgresql - 将 json 条目转换为表记录的最佳方法
- awk - 查找匹配的代码块并在倒数第二行添加或替换内容
- pdf - 从 PPTX 创建可访问的 PDF - 对某些句子不起作用 - 为什么?
- c++ - Quectel EC25 发送短信并收到+CMS ERROR 305