Chart.js tuvali yeniden boyutlandırma


87

( Android WebView HTML5 tuval hatası ) 'da Graph.js kitaplığını kullanarak grafiklerin çizimiyle ilgili bir soru yayınladım. Şu an sahip olduğum sorun, grafiği birden çok kez çizmek için işlevi çağırırsam, tuval her seferinde yeniden boyutlandırılır. Grafik aynı tuvale her yeniden çizildiğinde boyutu da değişir. Ayrıca tuvalin boyutunu ayarlamayı denedim ama başarılı olamadım.

Nedeni ne olabilir? Tuval neden her seferinde yeniden boyutlandırılıyor?


Şimdi, Chart.js'nin resmi web sitesinde buna ayrılmış sayfaları: chartjs.org/docs/latest/general/responsive.html Çözümü test etti ve gayet iyi çalışıyor.
Amine27

Yanıtlar:


178

Bununla ilgili pek çok sorun yaşadım, çünkü tüm bunlardan sonra, fare gezinirken çizgi grafiğim berbat görünüyordu ve bunu yapmanın daha basit bir yolunu buldum, umarım yardımcı olur :)

Şu Chart.js seçeneklerini kullanın:

// 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,

Cevap için teşekkürler @ NoFlag. Benim için yükseklik ve genişlik nitelikleri tuvale uygulanmıyordu, çünkü burada herhangi birinin tuvali yeniden boyutlandırmaya çalışmak için bir çözüm araması durumunda, doğruya duyarlı ayarlamayı deneyin. * Chart.defaults.global.responsive = false *
sghosh968

14
Unutmayın, bu yöntemin düzgün çalışması için, tuvali a içine yerleştirmeniz ve tuval yerine <div>adı geçen yüksekliği ve / veya genişliği ayarlamanız gerekir <div>.
totymedli

2
Bu bayraklar artık varsayılan olarak şu şekilde ayarlanmıştır true, bu nedenle onlara dokunmanıza gerek yoktur: chartjs.org/docs/latest/general/responsive.html
João Pimentel Ferreira

Bununla birlikte, tuvalin genişliğini ve yüksekliğini de ayarlayın. O zaman iyi çalışıyor. Teşekkürler
Mazhar MIK

63

Olan şey, Chart.js'nin çağrıldığında tuvalin boyutunu çoğaltması ve ardından CSS kullanarak onu küçültmeyi denemesi, amacı yüksek dpi cihazlar için daha yüksek çözünürlüklü grafikler sağlamaktır.

Sorun şu ki, bunu zaten yaptığının farkında değil, bu yüzden ardışık zamanlar çağrıldığında, işler bozulmaya başlayana kadar zaten (iki katına çıkmış veya her neyse) boyutu TEKRAR çarpıyor. (Aslında olan şey, genişlik ve yükseklik için DOM özniteliğini değiştirerek, bunu bir faktörle, genellikle 2 ile çarparak, sonra bunu değiştirerek ve sonra css stilini değiştirerek tuvale daha fazla piksel ekleyip eklemeyeceğini kontrol etmektir. sayfada aynı boyutu korumak için özellik.)

Örneğin, bir kez çalıştırdığınızda ve tuval genişliğiniz ve yüksekliğiniz 300 olarak ayarlandığında, bunları 600 olarak ayarlar, ardından stil özelliğini 300 olarak değiştirir ... ancak yeniden çalıştırırsanız, DOM genişliğini ve yüksekliğini görür. 600'dür (nedenini görmek için bu sorunun diğer cevabını kontrol edin) ve ardından bunu 1200'e ve css genişliğini ve yüksekliğini 600'e ayarlar.

En zarif çözüm değil, ancak bu sorunu, Chart.js'ye yapılan her ardışık çağrıdan önce tuvalin genişliğini ve yüksekliğini manuel olarak ayarlayarak retina cihazları için gelişmiş çözünürlüğü korurken çözdüm.

var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);

1
Bu hatayla karşılaştım: Yakalanmamış Referans Hatası: doughnutVeri tanımlanmadı
Dulith De Costa

11
Err. evet, bu sadece bir yer tutucu değişkendir, çünkü hangi verilerin grafiğini çizmeye çalıştığınızı bilmiyorum.
jcmiller11

27

Bu benim için çalışıyor:

<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>

Temel gerçek, tuvalin boyutunu div etiketinde ayarlamamız gerektiğidir.


Katılıyorum! sadece tuvali bir div içine yerleştirin, ardından 'duyarlı' seçeneğinin yanlış OLMADIĞINDAN emin olun (varsayılan olarak doğrudur). Daha sonra boyutlandırma kuralını div'e uygulayın.
NoelB

20

IOS ve Android'de, siz kaydırma yaptığınızda tarayıcı araç çubuğunu gizler, böylece, grafiği yeniden boyutlandırmak için kurşun çizelgelerini döndüren pencerenin boyutunu değiştirir. Çözüm, en boy oranını korumaktır.

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

Bu probleminizi çözmeli.


6

Jcmiller11'in önerdiği gibi, genişliği ve yüksekliği ayarlamak yardımcı olur. Biraz daha hoş bir çözüm, grafiği çizmeden önce tuvalin genişliğini ve yüksekliğini almaktır. Ardından, grafiğin sonraki her yeniden çizilmesinde grafiği ayarlamak için bu sayıları kullanın. Bu, javascript kodunda sabit olmamasını sağlar.

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

Pardon, bunun nasıl çalıştığını açıklayabilir misin? Örneğin, bir sayfa açarsam tuvalin bir boyutu olur, ancak bu durumda pencereyi ve tuvalin boyutunu değiştirirsem (ve muhtemelen orijinal boyuta ihtiyacım yok çünkü pencerenin önceki boyutu için)?
kiradotee

6

Burada bazı ufak tefek ince ayarlarla birden fazla cevabın bir kombinasyonunu kullanmak zorunda kaldım.

İlk olarak, kanvas elemanını blok düzeyinde bir kap içine sarmalamanız gerekir . Ben do, size diyorum değil tuval eleman herhangi kardeşleri atalım; inatçı ve şımarık olduğu için yalnız bir çocuk olsun . (Ambalajın üzerinde herhangi bir boyutlandırma kısıtlamasına ihtiyacı olmayabilir, ancak güvenlik için üzerine maksimum yüksekliğin uygulanması iyi olabilir.)

Önceki koşulların karşılandığından emin olduktan sonra, grafiği başlatırken aşağıdaki seçeneklerin kullanıldığından emin olun:

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

Grafiğin yüksekliğini ayarlamak istiyorsanız, bunu tuval öğesi seviyesinde yapın.

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

Çocukla başka herhangi bir şekilde ilgilenmeye çalışmayın. Bu, beşiğinde huzur içinde kalan, tatmin edici, düzgün bir şekilde düzenlenmiş bir tabloyla sonuçlanmalıdır.


3

Benzer bir sorun yaşadım ve cevabınızı buldum .. Sonunda bir çözüme ulaştım.

Görünüşe göre Chart.js kaynağında aşağıdakiler var (muhtemelen aynı tuvalde yeniden oluşturmaması ve tamamen farklı bir grafiğin olması gerektiği için):

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

Bu, bir kez çağrılırsa sorun değildir, ancak birden çok kez yeniden çizdiğinizde, tuval DOM öğesinin boyutunu birden çok kez değiştirerek yeniden boyutlandırmaya neden olursunuz.

Umarım yardımcı olur!


1

Herhangi biri sorun yaşıyorsa, yanıt verme yeteneğinden ödün vermeyi vb. İçermeyen bir çözüm buldum.

Grafik yapıcısını çağırmadan önce tuvalinizi bir div kabına sarın (stil yok) ve div içeriğini kimliğiyle boş bir tuvale sıfırlayın.

Misal:

HTML:

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

JS:

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

1

Canvas'ı jQuery kullanarak Yeniden Boyutlandırmayı denedim ama iyi çalışmıyor. Bence CSS3 belirli düzeyde yakınlaştırma vurgulu üzerinde isterseniz, üzerinde deneyebilirsiniz en iyi seçenektir.

Diğer codepan bağlantısından üzerine gelme seçeneğinin ardından:

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

Codepan bağlantımı izleyin:

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


1

Ben de aynı sorunu yaşıyordum. Şu seçeneği ayarlayarak çözebildim:

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

Ve css'de, kapsayıcı div genişliğini tuval ile aynı şekilde ayarlayın:

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


0

Angular CLI kullanırken aynı türden bir ölçeklendirme sorunu yaşadım. Bu satırı index.html'den kaldırarak çalıştırmayı başardı:

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

ve sonra açısal-cli.json dosyasında, komut dosyaları bölümünde şunu kullanarak:

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

Kaynak : mikebarr58


-4

Ekle divve sorunu çözecek

<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>

-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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.