W ( Błąd kanwy HTML5 Android WebView ) opublikowałem pytanie dotyczące kreślenia wykresów za pomocą biblioteki Graph.js. Problem, który mam teraz, polega na tym, że jeśli wywołuję funkcję w celu wielokrotnego wykreślania wykresu, płótno zmienia rozmiar za każdym razem. Za każdym razem, gdy wykres jest przerysowywany do tego samego obszaru roboczego, jego rozmiar również się zmienia. Próbowałem też ustawić rozmiar płótna, ale bezskutecznie.
Jaki może być tego powód? Dlaczego płótno zmienia rozmiar za każdym razem?
Odpowiedzi:
Miałem z tym sporo problemów, bo po tym wszystkim moja grafika liniowa wyglądała fatalnie po najechaniu myszą i znalazłem prostszy sposób na zrobienie tego, mam nadzieję, że to pomoże :)
Użyj tych opcji Chart.js:
// 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,
źródło
<div>
i ustawić wysokość i / lub szerokość na wspomnianym<div>
zamiast płótnie.true
, więc nie musisz ich dotykać: chartjs.org/docs/latest/general/responsive.htmlTo, co się dzieje, to Chart.js mnoży rozmiar płótna, gdy jest wywoływany, a następnie próbuje zmniejszyć go z powrotem za pomocą CSS, aby zapewnić wykresy o wyższej rozdzielczości dla urządzeń o wysokiej rozdzielczości.
Problem polega na tym, że nie zdaje sobie sprawy, że już to zrobił, więc gdy wywołuje się kolejne czasy, mnoży już (podwojony lub cokolwiek) rozmiar PONOWNIE, aż wszystko zacznie się psuć. (To, co faktycznie się dzieje, to sprawdzenie, czy powinno dodać więcej pikseli do płótna, zmieniając atrybut DOM dla szerokości i wysokości, jeśli powinien, mnożąc go przez jakiś współczynnik, zwykle 2, następnie zmieniając to, a następnie zmieniając styl css atrybut, aby zachować ten sam rozmiar na stronie.)
Na przykład, jeśli uruchomisz go raz, a szerokość i wysokość obszaru roboczego są ustawione na 300, ustawia je na 600, a następnie zmienia atrybut stylu na 300 ... ale jeśli uruchomisz go ponownie, zobaczy, że szerokość i wysokość DOM wynosi 600 (sprawdź inną odpowiedź na to pytanie, aby zobaczyć, dlaczego), a następnie ustawia ją na 1200, a szerokość i wysokość css na 600.
Nie jest to najbardziej eleganckie rozwiązanie, ale rozwiązałem ten problem, zachowując zwiększoną rozdzielczość dla urządzeń siatkówkowych, po prostu ustawiając szerokość i wysokość płótna ręcznie przed każdym kolejnym wywołaniem Chart.js
var ctx = document.getElementById("canvas").getContext("2d"); ctx.canvas.width = 300; ctx.canvas.height = 300; var myDoughnut = new Chart(ctx).Doughnut(doughnutData);
źródło
To działa dla mnie:
<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>
Zasadniczym faktem jest to, że musimy ustawić rozmiar płótna w znaczniku DIV.
źródło
W systemach IOS i Android przeglądarka ukrywa pasek narzędzi podczas przewijania, zmieniając w ten sposób rozmiar okna, które prowadzi chartjs do zmiany rozmiaru wykresu. Rozwiązaniem jest zachowanie proporcji.
var options = { responsive: true, maintainAspectRatio: true }
To powinno rozwiązać twój problem.
źródło
Jak zasugerował jcmiller11, pomaga ustawienie szerokości i wysokości. Nieco ładniejszym rozwiązaniem jest pobranie szerokości i wysokości płótna przed narysowaniem wykresu. Następnie używając tych liczb do ustawienia wykresu przy każdym kolejnym ponownym losowaniu wykresu. Daje to pewność, że w kodzie javascript nie ma stałych.
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); }
źródło
Musiałem tu użyć kombinacji wielu odpowiedzi z kilkoma drobnymi poprawkami.
Po pierwsze, konieczne jest zawinięcie elementu canvas w kontenerze blokowym. Mówię wam, nie pozwólcie, aby element canvas miał rodzeństwo; niech będzie samotnym dzieckiem, bo jest uparte i zepsute . (Owijka może nie wymagać żadnych ograniczeń rozmiaru, ale ze względów bezpieczeństwa dobrze jest ustawić maksymalną wysokość).
Po upewnieniu się, że poprzednie warunki są spełnione, podczas inicjowania wykresu upewnij się, że używane są następujące opcje:
var options = { "responsive": true, "maintainAspectRatio": false }
Jeśli chcesz dostosować wysokość wykresu, zrób to na poziomie elementu canvas.
<canvas height="500"></canvas>
Nie próbuj obchodzić się z dzieckiem w żaden inny sposób. Powinno to skutkować satysfakcjonującym, odpowiednio rozplanowanym wykresem, który spokojnie pozostaje w łóżeczku.
źródło
Miałem podobny problem i znalazłem twoją odpowiedź… W końcu doszedłem do rozwiązania.
Wygląda na to, że źródło Chart.js ma następujące cechy (prawdopodobnie dlatego, że nie powinno ponownie renderować i zupełnie innego wykresu na tym samym płótnie):
//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); }
Jest to dobre, jeśli zostanie wywołane raz, ale gdy przerysowujesz wielokrotnie, w końcu wielokrotnie zmieniasz rozmiar elementu Canvas DOM, powodując zmianę rozmiaru.
Mam nadzieję, że to pomoże!
źródło
Jeśli ktoś ma problemy, znalazłem rozwiązanie, które nie wymaga poświęcania czasu reakcji itp.
Po prostu zawiń płótno w kontenerze div (bez stylów) i zresetuj zawartość div do pustego obszaru roboczego z identyfikatorem przed wywołaniem konstruktora Chart.
Przykład:
HTML:
<div id="chartContainer"> <canvas id="myChart"></canvas> </div>
JS:
$("#chartContainer").html('<canvas id="myChart"></canvas>'); //call new Chart() as usual
źródło
Próbowałem zmienić rozmiar płótna za pomocą jQuery, ale nie działa dobrze. Myślę, że CSS3 to najlepsza opcja, którą możesz wypróbować, jeśli chcesz ustawić powiększanie na określonym poziomie.
Po opcji najechania kursorem z innego linku do panelu kodu
.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); }
Śledź mój link do panelu kodowego:
https://codepen.io/hitman0775/pen/XZZzqN
źródło
Miałem ten sam problem. Udało mi się to rozwiązać, ustawiając opcję:
responsive: false, maintainAspectRatio: true, showScale: false,
A w css ustaw szerokość elementu div kontenera na taką samą jak kanwa:
#canvasContainer { width: 300px; } canvas { width: 300px; }
źródło
Miałem ten sam problem ze skalowaniem, jak przy użyciu Angular CLI. Udało mi się go uruchomić, usuwając ten wiersz z pliku index.html:
<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>
a następnie w pliku angular-cli.json, w sekcji skryptów, używając tego:
"scripts": ["../node_modules/chart.js/dist/Chart.bundle.min.js"]
Źródło : mikebarr58
źródło
Dodaj,
div
a to rozwiąże problem<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>
źródło
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);
źródło