Bootstrap 3选项卡& Chart.js - 未在标签

时间:2015-04-25 06:08:37

标签: javascript twitter-bootstrap twitter-bootstrap-3 chart.js

我正在使用Bootstrap 3 tabs进行页面布局,使用Chart.js为项目创建圆环图。

但是,在更改为带有图表的选项卡时,图表不会加载。有时,当你开始检查谷歌浏览器中的元素时,它们会加载。 如果它们在第一个可见选项卡上加载,它们似乎只会渲染。

chrome控制台中的chart.js javascript存在一个已知错误:

  

Uncaught IndexSizeError:无法在'CanvasRenderingContext2D'上执行'arc':提供的半径(-0.5)为负。

我认为这是因为Bootstrap将标签可见性设置为无,因此图表无法正确呈现或者某些内容......

应该是这样的:

enter image description here

有没有其他人有这个问题&如果是这样;有解决方法吗?

...或者我应该寻找另一个与Bootstrap标签很好地匹配的图表脚本。

提前谢谢你:)

5 个答案:

答案 0 :(得分:10)

我遇到了这个问题。如果我没记错的话,当使用shown.bs.tabhttp://getbootstrap.com/javascript/#tabs)显示活动标签时,我通过调用图表js渲染来解决它 即。

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  e.target // newly activated tab
  //call chart to render here
});

希望有所帮助。

答案 1 :(得分:5)

由于这个问题的根源在bootstrap中没有显示tab-content,所以我用一点css hack解决了这个问题。

.tab-content>.tab-pane {
    display: block;
    height: 0;
    overflow: hidden;
}
.tab-content>.tab-pane.active {
    height: auto;
}

答案 2 :(得分:1)

对我而言,解决方案很简单。使用最新的提交,更新Chart.Arc函数,如下所示:

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();
    }
}

});

需要注意的是内半径和外半径上的三元运算符,以防止负值。这对我的项目来说就像一个魅力。图表继续响应,并且通过将半径转换为自然数字(即:正数)没有任何有害影响

答案 3 :(得分:0)

谷歌搜索得到了这个小提琴。这可能会有所帮助。 http://jsfiddle.net/woqsazau/2/

HTML:

<div class="container">
    <!-- Nav tabs -->
    <ul class="nav nav-tabs" role="tablist" id="bs-tabs">
        <li><a href="#length" role="tab" data-toggle="tab">Length</a>

        </li>
        <li class="active"><a href="#height" role="tab" data-toggle="tab">Height</a>

        </li>
    </ul>
    <!-- Tab panes -->
    <div class="tab-content">
        <div class="tab-pane" id="length">
            <div class="canvas-holder">
                <canvas id="lengthChart" class="chart"></canvas>
            </div>
        </div>
        <div class="tab-pane active" id="height">
            <div class="canvas-holder">
                <canvas id="heightChart" class="chart"></canvas>
            </div>
        </div>
    </div>
</div>

JS:

 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");
    });
});

答案 4 :(得分:0)

我找到了一个相当容易且有些懒惰的选择。您可以将所有标签设置为&#34; tab-pane active&#34;这样,选项卡上的所有图表都会显示和渲染,然后

setTimeout(yourFunction, 250);
function yourFunction()
{
$('.nav-tabs a[href="#anytabExceptdefault"]').tab('show')
$('.nav-tabs a[href="#backtoyourdefaultTab"]').tab('show')