Змінення розміру полотна Chart.js


86

У ( Помилка полотна Android WebView HTML5 ) я опублікував запитання щодо побудови графіків за допомогою бібліотеки Graph.js. Проблема, яку я маю зараз, полягає в тому, що якщо я викликаю функцію для побудови графіку кілька разів, полотно кожного разу змінюється. Щоразу, коли графік перемальовується на одне і те ж полотно, його розмір також змінюється. Я також спробував встановити розмір полотна, але безуспішно.

Що може бути причиною? Чому полотно кожного разу змінює розмір?


Тепер їх сторінка присвячена цій веб-сторінці на офіційному веб-сайті Chart.js, тут: chartjs.org/docs/latest/general/responsive.html Перевірено рішення, і воно працює чудово.
Амін 27

Відповіді:


175

У мене було багато проблем, тому що після всього цього моя графіка лінії виглядала жахливо при наведенні миші, і я знайшов простіший спосіб зробити це, сподіваюся, це допоможе :)

Скористайтеся цими параметрами 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,

Дякую @NoFlag за відповідь. Для мене атрибути висоти та ширини не застосовувалися до полотна, якщо хтось опиниться тут, шукаючи рішення для спроби змінити розмір полотна, спробуйте встановити відповідне значення true. * Chart.defaults.global.responsive = false *
sghosh968

13
Не забувайте, що для того, щоб цей метод працював належним чином, вам потрібно помістити полотно в a <div>та встановити висоту та / або ширину на вказаному <div>замість полотна.
totymedli

2
Зараз ці прапори встановлені за замовчуванням true, тому вам не потрібно їх торкатися: chartjs.org/docs/latest/general/responsive.html
Жоао Піментель Феррейра

Поряд з цим встановіть також ширину та висоту полотна. Тоді це працює нормально. Дякуємо
Мажар МІК

63

Те, що відбувається, це Chart.js множує розмір полотна при його виклику, а потім намагається зменшити його за допомогою CSS, метою якого є надання графіків з більш високою роздільною здатністю для пристроїв із високою точністю в дюйм.

Проблема полягає в тому, що він не усвідомлює, що це вже робив, тому, коли його називають послідовними часами, він ЗНО Змножує вже (вдвічі або більше), поки все не почне ламатися. (Що насправді відбувається, це перевірка, чи слід додавати більше пікселів на полотно, змінюючи атрибут DOM на ширину та висоту, якщо потрібно, помножуючи його на якийсь коефіцієнт, зазвичай 2, потім змінюючи це, а потім змінюючи стиль css для збереження однакового розміру на сторінці.)

Наприклад, коли ви запускаєте його один раз, а ширина і висота полотна встановлені на 300, він встановлює їх на 600, потім змінює атрибут стилю на 300 ... але якщо ви запускаєте його знову, він бачить, що ширина і висота DOM дорівнюють 600 (перевірте іншу відповідь на це запитання, щоб зрозуміти чому), а потім встановіть його на 1200, а ширину та висоту css до 600.

Не найелегантніше рішення, але я вирішив цю проблему, зберігаючи підвищену роздільну здатність для пристроїв сітківки, просто встановлюючи ширину та висоту полотна вручну перед кожним наступним викликом Chart.js

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

Я натрапив на цю помилку: Uncaught ReferenceError: testonutData не визначено
Дуліт Де Коста

11
Помилка так, це просто змінна-заповнювач там, оскільки я просто не знаю, які дані ви намагалися зобразити.
jcmiller11

26

Це працює для мене:

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

Суттєвий факт полягає в тому, що ми повинні встановити розмір полотна в тегу div.


погодьтесь! просто помістіть полотно всередину div, а потім переконайтеся, що параметр 'responsive' НЕ є хибним (це типово за замовчуванням). Тоді просто застосуйте правило розміру до div.
NoelB

20

У IOS та Android браузер приховує панель інструментів під час прокрутки, змінюючи тим самим розмір вікна, яке призводить до того, щоб графіки змінили розмір графіку. Рішення полягає в підтримці пропорції.

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

Це має вирішити вашу проблему.


6

Як запропонував jcmiller11, налаштування ширини та висоти допомагає. Трохи приємнішим рішенням є отримання ширини та висоти полотна перед тим, як малювати діаграму. Потім використовуйте ці цифри для встановлення діаграми при кожному наступному повторному малюванні діаграми. Це гарантує відсутність констант у коді 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); 
}

Вибачте, не могли б ви пояснити, як це працює? Наприклад, я відкриваю сторінку, тоді полотно має один розмір, але тоді, якщо я зміню розмір вікна, і полотно буде мати інший розмір (і, мабуть, мені не потрібен початковий розмір, оскільки він був для попереднього розміру вікна)?
kiradotee

6

Мені довелося використати тут комбінацію декількох відповідей із незначними налаштуваннями.

По-перше, потрібно обернути елемент полотна всередині контейнера рівня блоку. Я кажу вам, не дозволяйте елементу полотна мати братів і сестер; нехай це буде самотня дитина, бо вона вперта і зіпсована . (Обгортка може не потребувати жодних обмежень щодо розміру, але для безпеки може бути добре, якщо до неї буде застосовано максимальну висоту.)

Переконавшись, що попередні умови виконуються, при ініціюванні діаграми переконайтеся, що використовуються такі параметри:

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

Якщо ви хочете відрегулювати висоту діаграми, зробіть це на рівні елемента полотна.

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

Не намагайтеся мати справу з дитиною будь-яким іншим способом. Це має вийти на задовільно, правильно складеному графіку, який спокійно залишається в ліжечку.


3

У мене була подібна проблема і я знайшов вашу відповідь .. Зрештою я прийшов до рішення.

Схоже, джерело Chart.js має наступне (можливо, тому, що він не повинен повторно відображати і зовсім інший графік на одному полотні):

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

Це чудово, якщо його викликати один раз, але коли ви перемальовуєте кілька разів, ви в кінцевому підсумку змінюєте розмір елемента DOM полотна кілька разів, викликаючи повторний розмір.

Сподіваюся, це допоможе!


1

Якщо хтось має проблеми, я знайшов рішення, яке не передбачає жертвування реакцією тощо.

Просто оберніть своє полотно у контейнер div (без стилю) та скиньте вміст div до порожнього полотна з ідентифікатором перед викликом конструктора діаграми.

Приклад:

HTML:

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

JS:

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

1

Я намагався змінити розмір полотна за допомогою jQuery, але це не працює добре. Я думаю, що CSS3 - найкращий варіант, який ви можете спробувати, якщо ви хочете збільшити наведення курсору на певному рівні.

Наступний варіант наведення курсору з іншого посилання в кодовому коді:

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

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


1

У мене була та сама проблема. Я зміг це вирішити, встановивши параметр:

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

А в css встановіть ширину div контейнера такою ж, як і на полотні:

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


0

У мене були такі самі проблеми масштабування за допомогою Angular CLI. Змогла змусити його працювати, видаливши цей рядок з index.html:

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

а потім у файлі angular-cli.json, у розділі сценаріїв, використовуючи це:

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

Джерело : mikebarr58



-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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.