javascript - "Responsive"Chart.js图表​​比包含窗口高

标签 javascript css canvas html5-canvas chart.js

我正在使用 Chart.js 库创建一系列图表。我注意到,当指定选项“responsive:true”时,虽然 Canvas 确实将自身限制在页面宽度上,但它不会将自身限制在页面高度上,即使在全屏时也是如此。这里有一个 fiddle 来演示:http://jsfiddle.net/uxtb9wj9/

StackOverflow 要求我在代码中附上一个 jsfiddle 链接,所以这里是:

HTML

<div class="row chartArea">
<div class="col-md-12">
    <div class="chartArea">
        <canvas id="chart" style="height: auto !important;"></canvas>
    </div>
</div>
</div>

JS

function widgetCallback(response) {
    console.log("widgetCallback; response: " + JSON.stringify(response));
    var chartData = jQuery.parseJSON(response);

    //Some dummy values - delete later
    var labels = chartData['chart1']['labels'];
    var dataSet1Title = chartData['chart1']['dataTitle'];
    var dataSet2Title = chartData['chart2']['dataTitle'];
    var dataSet1Data = chartData['chart1']['data'];
    var dataSet2Data = chartData['chart2']['data'];

    Chart.types.Line.extend({
        name: "Line2Y",
        getScale: function (data) {
            var startPoint = this.options.scaleFontSize;
            var endPoint = this.chart.height - (this.options.scaleFontSize * 1.5) - 5;
            return Chart.helpers.calculateScaleRange(
            data,
            endPoint - startPoint,
            this.options.scaleFontSize,
            this.options.scaleBeginAtZero,
            this.options.scaleIntegersOnly,
            this.options.scaleLabel);
        },
        initialize: function (data) {
            var y2datasetLabels = [];
            var y2data = [];
            var y1data = [];
            data.datasets.forEach(function (dataset, i) {
                if (dataset.y2axis == true) {
                    y2datasetLabels.push(dataset.label);
                    y2data = y2data.concat(dataset.data);
                } else {
                    y1data = y1data.concat(dataset.data);
                }
            });

            // use the helper function to get the scale for both datasets
            var y1Scale = this.getScale(y1data);
            this.y2Scale = this.getScale(y2data);
            var normalizingFactor = y1Scale.max / this.y2Scale.max;

            // update y2 datasets
            data.datasets.forEach(function (dataset) {
                if (y2datasetLabels.indexOf(dataset.label) !== -1) {
                    dataset.data.forEach(function (e, j) {
                        dataset.data[j] = e * normalizingFactor;
                    })
                }
            })

            // denormalize tooltip for y2 datasets
            this.options.multiTooltipTemplate = function (d) {
                if (y2datasetLabels.indexOf(d.datasetLabel) !== -1) return Math.round(d.value / normalizingFactor, 6);
                else return d.value;
            }

            Chart.types.Line.prototype.initialize.apply(this, arguments);
        },
        draw: function () {
            this.scale.xScalePaddingLeft = 60;
            this.scale.xScalePaddingRight = this.scale.xScalePaddingLeft + 30;
            Chart.types.Line.prototype.draw.apply(this, arguments);

            this.chart.ctx.textAlign = "center";
            this.chart.ctx.textBaseline = "bottom";
            this.chart.ctx.fillStyle = "#666";

            var ctx = this.chart.ctx;
            ctx.save();
            // position
            var x = this.scale.xScalePaddingLeft * 0.4;
            var y = this.chart.height / 2;
            // change origin
            ctx.translate(x, y)
            // rotate text
            ctx.rotate(-90 * Math.PI / 180);
            ctx.fillText(this.datasets[0].label, 0, 0);
            ctx.fillText(this.datasets[1].label, 0, this.chart.width - 60);
            ctx.restore();

            var yStep = (this.scale.endPoint - this.scale.startPoint) / this.y2Scale.steps
            for (var i = 0, y = this.scale.endPoint, label = this.y2Scale.min;
            i <= this.y2Scale.steps;
            i++) {
                this.chart.ctx.fillText(label, this.chart.width - this.scale.xScalePaddingRight + 20, y);
                y -= yStep;
                label += this.y2Scale.stepValue
            }
        }
    });


    var lineChartData1 = {
        labels: labels,
        datasets: [{
            label: dataSet1Title,
            fillColor: "rgba(0,255,0,0.5)",
            strokeColor: "rgba(0,255,0,1)",
            pointColor: "rgba(0,255,0,1)",
            pointStrokeColor: "#fff",
            data: dataSet1Data
        }, {
            label: dataSet2Title,
            fillColor: "rgba(151,187,205,0.5)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
            pointStrokeColor: "#fff",
            data: dataSet2Data,
            y2axis: true
        }]
    }

    var ctx = document.getElementById("chart").getContext("2d");

    var myLine1 = new Chart(ctx).Line2Y(lineChartData1, {
        scaleBeginAtZero: true,
        scaleShowGridLines: false,
        responsive: true,
        scaleShowLabels: true,
        showTooltips: true,
        tooltipTemplate: "<%= datasetLabel %>: <%= value %>"
    });
}

var response = '{"chart1":{"data":["826","748","76","58"],"labels":["10-08","10-09","10-10","10-11"],"labelTitle":"Date","dataTitle":"Uniques","title":"Uniques"},"chart2":{"data":["2018.00","2095.40","156.00","23.76"],"labels":["10-08","10-09","10-10","10-11"],"labelTitle":"Date","dataTitle":"Revenue","title":"Revenue"},"title":"Chart Title"}';
widgetCallback(response);

外部资源

jQuery 2.1.4、Bootstrap CSS 3.0、Chart.js 1.0.2

(在 fiddle 中,只需将“结果”部分的大小调整为宽度的两倍左右,然后重新运行 fiddle 。)

如何让图表不仅限制窗口宽度而且限制高度?谢谢你!

最佳答案

我认为在您的案例中使用视口(viewport)高度是个好主意。这在 Javascript 中相当容易:

<html>
<head>
    <meta charset="utf-8"/>
    <title>TEST</title>
    <style>
        * {padding: 0; height: 0;}
        canvas { width: 100%; }
    </style>
</head>

<body>
<canvas id="chart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script>
    var data = {
        labels: ["January", "February", "March", "April", "May", "June", "July"],
        datasets: [
            {
                label: "My First dataset",
                fillColor: "rgba(220,220,220,0.2)",
                strokeColor: "rgba(220,220,220,1)",
                pointColor: "rgba(220,220,220,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(220,220,220,1)",
                data: [65, 59, 80, 81, 56, 55, 40]
            },
            {
                label: "My Second dataset",
                fillColor: "rgba(151,187,205,0.2)",
                strokeColor: "rgba(151,187,205,1)",
                pointColor: "rgba(151,187,205,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(151,187,205,1)",
                data: [28, 48, 40, 19, 86, 27, 90]
            }
        ]
    };
    var ctx = document.getElementById("chart").getContext("2d");
        ctx.canvas.style.height = window.innerHeight;
    var myLineChart = new Chart(ctx).Line(data);


</script>
</body>

</html>

关于javascript - "Responsive"Chart.js图表​​比包含窗口高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33638182/

相关文章:

javascript - 保留上次检索的数据表更改数据源 header

javascript - 谷歌地图 API 缩放后形状重复出现问题

internet-explorer - .htc 文件在旧版本的 IE 中是否是像 CSS3 那样的圆 Angular 的好习惯?

html - 用 Canvas 缩放

python - 在自定义像素网格上移动 Canvas 上的矩形

javascript - Jquery Cycle Slider - 快速点击打破 slider

javascript - Spotify Web API - 通过 native 移动应用程序而不是浏览器对用户进行身份验证?

html - CSS,悬停后保持更改

css - 放置图像

Java Canvas 绘图