Mengubah ukuran kanvas Chart.js

87

Dalam ( kesalahan kanvas HTML5 Android WebView ) saya memposting pertanyaan tentang merencanakan grafik menggunakan pustaka Graph.js. Masalah yang saya miliki sekarang adalah jika saya memanggil fungsi untuk memplot grafik beberapa kali, kanvas akan berubah ukuran setiap saat. Setiap kali grafik digambar ulang ke kanvas yang sama, ukurannya juga berubah. Saya juga mencoba mengatur ukuran kanvas tetapi tidak berhasil.

Apa alasannya? Mengapa kanvas berubah ukuran setiap saat?

Jaka
sumber
Sekarang halaman mereka didedikasikan untuk itu di situs resmi Chart.js, di sini: chartjs.org/docs/latest/general/responsive.html Menguji solusinya dan bekerja dengan baik.
Amine27

Jawaban:

178

Saya mengalami banyak masalah dengan itu, karena setelah semua itu grafik garis saya tampak buruk ketika mouse melayang dan saya menemukan cara yang lebih sederhana untuk melakukannya, semoga bisa membantu :)

Gunakan opsi Chart.js ini:

// Boolean - whether or not the chart should be responsive and resize when the browser does.

responsive: true,

// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container

maintainAspectRatio: false,
NoFlag
sumber
Terima kasih @NoFlag atas jawabannya. Bagi saya, atribut tinggi & lebar tidak diterapkan ke kanvas, jika ada orang yang berakhir di sini mencari solusi untuk mencoba mengubah ukuran kanvas, coba atur responsif ke true. * Chart.defaults.global.responsive = false *
sghosh968
14
Jangan lupa bahwa agar metode ini berfungsi dengan baik, Anda perlu menempatkan kanvas di a <div>dan mengatur tinggi dan / atau lebar pada kata <div>alih-alih kanvas.
totymedli
2
Bendera ini sekarang secara default disetel ke true, jadi Anda tidak perlu menyentuhnya: chartjs.org/docs/latest/general/responsive.html
João Pimentel Ferreira
Bersamaan dengan ini, atur juga lebar dan tinggi kanvas. Kemudian berfungsi dengan baik. Terima kasih
Mazhar MIK
63

Apa yang terjadi adalah Chart.js mengalikan ukuran kanvas ketika dipanggil kemudian mencoba untuk menurunkannya kembali menggunakan CSS, tujuannya adalah untuk menyediakan grafik resolusi yang lebih tinggi untuk perangkat dpi tinggi.

Masalahnya adalah ia tidak menyadari bahwa ia telah melakukan ini, jadi ketika dipanggil berkali-kali, ia mengalikan ukuran yang sudah (dua kali lipat atau apa pun) LAGI sampai hal-hal mulai rusak. (Apa yang sebenarnya terjadi adalah memeriksa apakah itu harus menambahkan lebih banyak piksel ke kanvas dengan mengubah atribut DOM untuk lebar dan tinggi, jika seharusnya, mengalikannya dengan beberapa faktor, biasanya 2, lalu mengubahnya, dan kemudian mengubah gaya css atribut untuk mempertahankan ukuran yang sama di halaman.)

Misalnya, ketika Anda menjalankannya sekali dan lebar dan tinggi kanvas Anda disetel ke 300, itu menetapkannya ke 600, lalu mengubah atribut gaya menjadi 300 ... tetapi jika Anda menjalankannya lagi, itu melihat bahwa lebar dan tinggi DOM adalah 600 (periksa jawaban lain untuk pertanyaan ini untuk mengetahui alasannya) dan kemudian setel ke 1200 dan lebar dan tinggi css menjadi 600.

Bukan solusi yang paling elegan, tetapi saya memecahkan masalah ini sambil mempertahankan resolusi yang ditingkatkan untuk perangkat retina hanya dengan mengatur lebar dan tinggi kanvas secara manual sebelum setiap panggilan berturut-turut ke Chart.js

var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);
jcmiller11
sumber
1
Saya menemukan kesalahan ini: Uncaught ReferenceError: doughnutData tidak ditentukan
Dulith De Costa
11
Berbuat salah. ya, itu hanya variabel placeholder di sana, karena saya sama sekali tidak tahu data apa yang Anda coba buat grafiknya.
jcmiller11
27

Ini bekerja untuk saya:

<body>
    <form>
        [...]
        <div style="position:absolute; top:60px; left:10px; width:500px; height:500px;">
            <canvas id="cv_values"></canvas>

            <script type="text/javascript">
                var indicatedValueData = {
                    labels: ["1", "2", "3"],
                    datasets: [
                        {
                            [...]
                        };

                var cv_values = document.getElementById("cv_values").getContext("2d");
                var myChart = new Chart(cv_values, { type: "line", data: indicatedValueData });
            </script>
        </div>
    </form>
</body>

Fakta penting adalah kita harus mengatur ukuran kanvas di tag-div.

Patrick Pirzer
sumber
setuju! cukup tempatkan kanvas di dalam div, lalu pastikan bahwa opsi untuk 'responsif' TIDAK salah (ini benar secara default). Kemudian, terapkan aturan ukuran ke div.
NoelB
20

Di iOS dan Android, browser menyembunyikan toolbar saat Anda menggulir, dengan demikian mengubah ukuran jendela yang mengubah grafik utama untuk mengubah ukuran grafik. Solusinya adalah menjaga aspek rasio.

var options = { 
    responsive: true,
    maintainAspectRatio: true
}

Ini seharusnya menyelesaikan masalah Anda.

Pradeep Rajashekar
sumber
6

Seperti yang disarankan jcmiller11, mengatur lebar dan tinggi membantu. Solusi yang sedikit lebih bagus adalah mengambil lebar dan tinggi kanvas sebelum menggambar grafik. Kemudian gunakan angka-angka itu untuk mengatur grafik pada setiap gambar ulang grafik berikutnya. Ini memastikan tidak ada konstanta dalam kode javascript.

ctx.canvas.originalwidth = ctx.canvas.width;
ctx.canvas.originalheight = ctx.canvas.height;

function drawchart() {
    ctx.canvas.width = ctx.canvas.originalwidth;
    ctx.canvas.height = ctx.canvas.originalheight;

    var chartctx = new Chart(ctx);
    myNewBarChart = chartctx.Bar(data, chartSettings); 
}
Segera
sumber
Maaf, bisakah Anda menjelaskan cara kerjanya? Misalnya saya membuka halaman maka kanvas memiliki satu ukuran, tetapi jika saya mengubah ukuran jendela dan kanvas akan memiliki ukuran yang berbeda (dan kiranya saya tidak memerlukan ukuran asli karena itu untuk ukuran jendela sebelumnya)?
Kiradotee
6

Saya harus menggunakan kombinasi beberapa jawaban di sini dengan beberapa perubahan kecil.

Pertama, Anda perlu membungkus elemen kanvas dalam penampung tingkat blok. Aku berkata kepadamu, jangan tidak membiarkan elemen kanvas punya saudara; biarlah ia menjadi anak yang kesepian, karena ia keras kepala dan manja . (Pembungkus mungkin tidak memerlukan batasan ukuran apa pun yang ditempatkan di atasnya, tetapi demi keamanan, mungkin baik untuk menerapkan tinggi-maksimal padanya.)

Setelah memastikan bahwa kondisi sebelumnya terpenuhi, saat memulai bagan, pastikan opsi berikut digunakan:

var options = { 
    "responsive": true,
    "maintainAspectRatio": false
}

Jika Anda ingin menyesuaikan tinggi diagram, lakukan di tingkat elemen kanvas.

<canvas height="500"></canvas>

Jangan mencoba menangani anak itu dengan cara lain apa pun. Ini akan menghasilkan bagan yang memuaskan dan ditata dengan baik, yang tetap berada di boksnya dengan damai.

truefusion
sumber
3

Saya memiliki masalah yang sama dan menemukan jawaban Anda .. Saya akhirnya menemukan solusi.

Sepertinya sumber Chart.js memiliki yang berikut (mungkin karena itu tidak seharusnya dirender ulang dan grafik yang sama sekali berbeda dalam kanvas yang sama):

    //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
if (window.devicePixelRatio) {
    context.canvas.style.width = width + "px";
    context.canvas.style.height = height + "px";
    context.canvas.height = height * window.devicePixelRatio;
    context.canvas.width = width * window.devicePixelRatio;
    context.scale(window.devicePixelRatio, window.devicePixelRatio);
}

Tidak masalah jika dipanggil sekali, tetapi saat Anda menggambar ulang beberapa kali, Anda akhirnya mengubah ukuran elemen DOM kanvas beberapa kali yang menyebabkan ukuran ulang.

Semoga membantu!

yahfree
sumber
1

Jika ada yang mengalami masalah, saya menemukan solusi yang tidak melibatkan mengorbankan daya tanggap, dll.

Cukup bungkus kanvas Anda dalam wadah div (tanpa gaya) dan setel ulang konten div ke kanvas kosong dengan ID sebelum memanggil konstruktor Bagan.

Contoh:

HTML:

<div id="chartContainer">
    <canvas id="myChart"></canvas>
</div>

JS:

$("#chartContainer").html('<canvas id="myChart"></canvas>');
//call new Chart() as usual
fpscolin.dll
sumber
1

Saya mencoba Mengubah Ukuran Kanvas menggunakan jQuery tetapi tidak berfungsi dengan baik. Saya pikir CSS3 adalah opsi terbaik yang dapat Anda coba, jika Anda ingin melakukan hover zoom pada level tertentu.

Mengikuti opsi hover dari tautan codepan lain:

.style_prevu_kit:hover{
    z-index: 2;
    -webkit-transition: all 200ms ease-in;
    -webkit-transform: scale(1.5);
    -ms-transition: all 200ms ease-in;
    -ms-transform: scale(1.5);   
    -moz-transition: all 200ms ease-in;
    -moz-transform: scale(1.5);
    transition: all 200ms ease-in;
    transform: scale(1.5);
}

Ikuti tautan codepan saya:

https://codepen.io/hitman0775/pen/XZZzqN

Hiten Patel
sumber
1

Saya mengalami masalah yang sama. Saya bisa menyelesaikannya dengan mengatur opsi:

responsive: false,
maintainAspectRatio: true,
showScale: false,

Dan di css, atur lebar div kontainer sama dengan kanvas:

    #canvasContainer { 
      width: 300px;
    }
    
    canvas {
      width: 300px;
    }

Nova Qiu
sumber
0

Saya memiliki masalah penskalaan yang sama dengan menggunakan Angular CLI. Bisa membuatnya bekerja dengan menghapus baris ini dari index.html:

<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>

dan kemudian di file angular-cli.json, di bagian skrip, menggunakan ini:

"scripts": ["../node_modules/chart.js/dist/Chart.bundle.min.js"]

Sumber : mikebarr58

Wouter Vanherck
sumber
-4

Tambahkan divdan itu akan menyelesaikan masalah

<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>
rishabh bhardwaj
sumber
-6
 let canvasBox = ReactDOM.findDOMNode(this.refs.canvasBox);
 let width = canvasBox.clientWidth;
 let height = canvasBox.clientHeight;
 let charts = ReactDOM.findDOMNode(this.refs.charts);
 let ctx = charts.getContext('2d');
 ctx.canvas.width = width;
 ctx.canvas.height = height;
 this.myChart = new Chart(ctx);
Robin ma
sumber