Bootstrap 3 tabs & Chart.js - charts not loading on tabs
我正在使用Bootstrap 3选项卡进行页面布局,并使用Chart.js为项目创建甜甜圈图。
但是,当更改为带有图表的选项卡时,图表不会加载。 有时候,当您开始检查google chrome中的元素时,它们会加载。
仅当将它们加载到第一个可见选项卡上时,它们才会呈现。
chrome控制台中的chart.js javascript存在一个已知错误:
Uncaught IndexSizeError: Failed to execute 'arc' on 'CanvasRenderingContext2D': The radius provided (-0.5) is negative.
我认为这是因为Bootstrap的标签可见性设置为none,因此图表无法正确显示或其他内容。
它应该看起来像这样:
还有其他人有这个问题吗? 有解决方法吗?
...或者我应该寻找另一个可以很好地与Bootstrap选项卡一起使用的图表脚本。
先感谢您 :)
由于此问题的根源是在引导程序中不显示任何制表符内容,因此我通过一点CSS hack解决了此问题。
1 2 3 4 5 6 7 8 | .tab-content>.tab-pane { display: block; height: 0; overflow: hidden; } .tab-content>.tab-pane.active { height: auto; } |
我有这个问题。如果我没记错的话,我会使用
即
1 2 3 4 | $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { e.target // newly activated tab //call chart to render here }); |
希望能有所帮助。
对我而言,解决方案非常简单。使用最新的提交,如下更新Chart.Arc函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | Chart.Arc = Chart.Element.extend({ inRange: function (chartX, chartY) { var pointRelativePosition = helpers.getAngleFromPoint(this, { x: chartX, y: chartY }); //Check if within the range of the open/close angle var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle), withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius); return (betweenAngles && withinRadius); //Ensure within the outside of the arc centre, but inside arc outer }, tooltipPosition: function () { var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2), rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius; return { x: this.x + (Math.cos(centreAngle) * rangeFromCentre), y: this.y + (Math.sin(centreAngle) * rangeFromCentre) }; }, draw: function (animationPercent) { var easingDecimal = animationPercent || 1; var ctx = this.ctx; var innerRadius = (this.innerRadius < 0) ? this.innerRadius * -1 : this.innerRadius; var outerRadius = (this.outerRadius < 0) ? this.outerRadius * -1 : this.outerRadius; ctx.beginPath(); ctx.arc(this.x, this.y, outerRadius, this.startAngle, this.endAngle); ctx.arc(this.x, this.y, innerRadius, this.endAngle, this.startAngle, true); ctx.closePath(); ctx.strokeStyle = this.strokeColor; ctx.lineWidth = this.strokeWidth; ctx.fillStyle = this.fillColor; ctx.fill(); ctx.lineJoin = 'bevel'; if (this.showStroke) { ctx.stroke(); } } |
});
需要注意的是内半径和外半径上的三元运算符,以防止出现负值。这对我的项目来说就像是一种魅力。图表继续保持响应状态,并且通过将半径转换为自然数(即:正数)没有有害影响
我发现了一个相当简单且有些懒惰的选择。您可以将所有标签设置为"活动标签窗格",这样,标签上的所有图表都会显示和呈现,然后
1 2 3 4 5 | setTimeout(yourFunction, 250); function yourFunction() { $('.nav-tabs a[href="#anytabExceptdefault"]').tab('show') $('.nav-tabs a[href="#backtoyourdefaultTab"]').tab('show') |
在Google搜索上弄了些小提琴。这可能会有所帮助。 http://jsfiddle.net/woqsazau/2/
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist" id="bs-tabs"> <li> Length </li> <li class="active">Height </li> </ul> <!-- Tab panes --> <canvas id="lengthChart" class="chart"></canvas> <canvas id="heightChart" class="chart"></canvas> |
JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | function getJSON() { var data = { "Series": { "height": [{ "Date":"2014-09-19", "Value": 85 }, { "Date":"2014-09-23", "Value": 74 }] } }; console.log(data); var series = {}; // This loop is looping across all the series. // x will have all the series names (heights, lengths, etc.). for (var x in data.Series) { var dates = []; var values = []; // Loop across all the measurements for every serie. for (var i = 0; i < data.Series[x].length; i++) { var obj = data.Series[x][i]; // Assuming that all the different series (heights, lengths, etc.) have the same two Date, Value attributes. dates.push(moment(obj.Date).format("MMMM Mo")); values.push(obj.Value); } // Keep the list of dates and values by serie name. series[x] = { dates: dates, values: values }; } console.log(series.height.dates); console.log(series.height.values); //--------- //valueArray.push(Value); //dateArray.push(moment(date).format("MMMM Mo")); var dataArray = { labels: series.height.dates, datasets: [{ label:"Height", strokeColor:"rgb(26, 188, 156)", pointColor:"rgba(220,220,220,1)", pointStrokeColor:"#fff", pointHighlightFill:"#fff", pointHighlightStroke:"rgba(220,220,220,1)", data: series.height.values }] }; function chartFunc(dataArray) { var ctx = document.getElementById("heightChart").getContext("2d"); var myLineChart = new Chart(ctx).Line(dataArray, { scaleShowGridLines: true, bezierCurve: true, bezierCurveTension: 0.4, datasetStroke: false, fillColor:"rgba(0,0,0,0)", datasetFill: false, responsive: true, showTooltips: true, animation: false }); } //chartFunc chartFunc(dataArray); } //getJSON $(document).ready(function () { getJSON(); $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) { console.log("tab changed"); }); }); |