Линейная диаграмма Chartjs мигает между старыми и новыми данными при наведении - PullRequest
0 голосов
/ 04 октября 2019

Моя проблема не в создании диаграммы, а в том, что я ввожу новые значения для начальной частоты и конечной частоты, которые являются первым и последним значениями моего массива оси x после вызова getFreq() , график зависает при наведении курсора, переходя назад и вперед между старыми данными и новыми данными. Может кто-нибудь помочь мне выяснить, как удалить старые данные и создать / обновить новую диаграмму, где диаграмма не мерцает? Мой код показан ниже.

let Conductivity = document.getElementById('Conductivity');
let StartFreq = document.getElementById('StartFreq');
let StopFreq = document.getElementById('StopFreq');
let a = document.getElementById('a');
let b = document.getElementById('b');
let unitInch = document.getElementById('unitInch');
let test = document.getElementById('test');
let diameter = document.getElementById('Diameter');
let ctx = document.getElementById('myChart').getContext('2d');


function generateLabels(){
    // To generate the xa xis intervals
    let xaxis = [];
    for (let i = 0; i <= 10; i++) {
        let valToAppend = Math.round((parseFloat(StartFreq.value) + (parseFloat(StopFreq.value)-parseFloat(StartFreq.value)) / 10 * i)*100)/100;
        if (valToAppend <= parseFloat(StopFreq.value)){
            xaxis.push(valToAppend)
        }

    }
    return xaxis
}
function getFreq(){
    let x = generateLabels();
    let freq = [];
    let start = x[0];
    freq.push(start);
    let end = x[x.length - 1];
    for (let i=0; i < 4 * (end-start);i++){
        let lastfreq = freq[freq.length - 1];
        freq.push(lastfreq + 0.25)
    }
    // let rklen = freq.length;

    return freq
}


function getRS(){
    let RS = [];
    let freq = getFreq();
    freq.forEach(element =>{
        let RStoAppend = Math.sqrt((2*Math.PI*(Math.pow(10,9)*element)*(4*Math.PI*Math.pow(10,-7)))/(2*(parseFloat(Conductivity.value)*Math.pow(10,7))))     ;
        RS.push(RStoAppend)
    });
    return RS

}
function getRK(){
    let RK = [];
    let freq = getFreq();
    freq.forEach(element => {
        let RKtoappend = (2*Math.PI*(element * Math.pow(10,9))) / (3* Math.pow(10,8));
        RK.push(RKtoappend)
    });

    return RK
}
function getRbeta(){
    let Rbeta = [];
    let RK = getRK();
    RK.forEach(element => {
        let Rbetatoappend = Math.sqrt(Math.pow(element,2) - Math.pow((Math.PI/(parseFloat(a.value)*25.4/1000)),2));
        Rbeta.push(Rbetatoappend);
    });


    return Rbeta;
}
function getRatte(){
    let Ratte = [];
    let RS = getRS();
    let RK = getRK();
    let Rbeta = getRbeta();
    for (let i = 0; i < RS.length ;i++){
        let Rattetoappend = RS[i]*(2*(25.4/1000*parseFloat(b.value))*Math.pow(Math.PI,2)+Math.pow((parseFloat(a.value)*25.4/1000),3)*Math.pow(RK[i],2))/(Math.pow((parseFloat(a.value)*25.4/1000),3)*(25.4/1000*parseFloat(b.value))*Rbeta[i]*RK[i]*377)/(1000/25.4);
        Ratte.push(Rattetoappend);
    }
    // test.innerHTML = '<td id="test">' + Ratte + '<td>';

    return Ratte
}
function getRTE10(){
    let RTE10 = [];
    let Ratte = getRatte();
    Ratte.forEach(element => {
        if (isNaN(-20*Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))) {
            RTE10.push(0)
        }
        else {
            RTE10.push(-20 * Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))
        }
    });


    return RTE10
}
//////////////////////// For CTE11/////////////
function getk(){
    let k = [];
    let freq = getFreq();
    freq.forEach(element => {
        k.push(2*Math.PI*element*Math.pow(10,9)/(3*Math.pow(10,8)))
    });
    return k
}
function getbeta(){
    let beta = [];
    let k = getk();
    k.forEach(element => {
        beta.push(Math.sqrt(Math.pow(element,2)-Math.pow((1.8412/(parseFloat(diameter.value)/2*25.4/1000)),2)))
    });
    return beta
}
function getTE11_1(){
    let TE11_1 = [];
    let k = getk();
    let rs = getRS();
    let beta = getbeta();
    for (let i = 0; i < rs.length ;i++){
        TE11_1.push(rs[i]*(Math.pow((1.8412/(parseFloat(diameter.value)/2*25.4/1000)),2)+Math.pow(k[i],2)/(Math.pow(1.8414,2)-1))/((parseFloat(diameter.value)/2*25.4/1000)*k[i]*beta[i]*377)/(1000/25.4));
    }
    return TE11_1
}

function getCTE11(){
    let CTE11 = [];
    let TE11_1 = getTE11_1();
    TE11_1.forEach(element => {
        if (isNaN(-20 * Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))) {
            CTE11.push(0)
        }
        else {
            CTE11.push(-20 * Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))
        }
    });
   // test.innerHTML = '<td id="test">' + CTE11 + '<td>';
    return CTE11
}

function getTM01(){
    let TM01 = [];
    let rs = getRS();
    let freq = getFreq();
    for (let i = 0; i < rs.length ;i++){
        TM01.push(rs[i]/((parseFloat(diameter.value)/2 *25.4/1000)*377*Math.sqrt(1-Math.pow(((2.4049/(2*Math.PI*parseFloat(diameter.value)/2 *25.4/1000)*0.3)*Math.pow(10,9)/(freq[i]*Math.pow(10,9))),2)))/(1000/25.4));
    }
    return TM01

}

function getCTM01(){
    let CTM01 = [];
    let TM01 = getTM01();

    TM01.forEach(element => {
        if (isNaN(-20 * Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))) {
            CTM01.push(0)
        }
        else {
            CTM01.push(-20 * Math.log10(Math.exp(-element)) * parseFloat(unitInch.value))
        }
    });
    return CTM01
}


function getAt2(){
    let at2 = [];
    let freq = getFreq();
    freq.forEach(element =>{
       at2.push(Math.pow(((3.8318/(2*Math.PI*parseFloat(diameter.value)/2 *25.4/1000)*0.3)*Math.pow(10,9)/(element*Math.pow(10,9))),2)+1/(Math.pow(3.8318,2)-1))
    });

    return at2
}
function getAt1(){
    let at1 = [];
    let freq = getFreq();
    let rs = getRS();
    for (let i = 0; i < rs.length ;i++){
        at1.push(rs[i]/(parseFloat(diameter.value)/2 *25.4/1000*377*Math.sqrt(1-Math.pow(((3.8318/(2*Math.PI*parseFloat(diameter.value)/2 *25.4/1000)*0.3)*Math.pow(10,9)/(freq[i]*Math.pow(10,9))),2)))/(1000/25.4));
    }
    return at1
}

function getCTE01(){
    let CTE01 = [];
    let at1 = getAt1();
    let at2 = getAt2();
    for(let i = 0;i < at1.length; i++){
        if (isNaN((-20*Math.log10(Math.exp(-(at1[i]*at2[i])))*parseFloat(unitInch.value)))) {
            CTE01.push(0)
        }
        else {
            CTE01.push(-20 * Math.log10(Math.exp(-(at1[i] * at2[i]))) * parseFloat(unitInch.value))
        }
        }
    return CTE01
}

function getdata(){
    let data =[];
    let xaxis = getFreq();
    let RTE10 = getRTE10();
    let CTE11 = getCTE11();
    let CTM01 = getCTM01();
    let CTE01 = getCTE01();
    data.push(xaxis,RTE10,CTE11,CTM01,CTE01);
    return data
}


function draw_chart(data) {
    let chart = new Chart(ctx, {

        // The type of chart we want to create
        type: 'line',

        // The data for our dataset
        data: {
            labels: data[0],
            datasets: [{
                label: 'R-TE10',
                data: data[1],
                pointStyle : 'line',
                backgroundColor: 'transparent',
                borderColor: 'blue',
                pointRadius: '0'
            },{
                label: 'C-TE11',
                data: data[2],
                pointStyle : 'line',
                backgroundColor: 'transparent',
                borderColor: 'orange',
                pointRadius: '0'
            },{
                label: 'C-TM01',
                data: data[3],
                pointStyle : 'line',
                backgroundColor: 'transparent',
                borderColor: 'green',
                pointRadius: '0'
            },{
                label: 'C-TE01',
                data: data[4],
                pointStyle : 'line',
                backgroundColor: 'transparent',
                borderColor: 'red',
                pointRadius: '0'
            }]
        },

        // Configuration options go here
        options: {
            responsive : true,
            scales: {
                xAxes :[{
                    ticks: {
                        min: StartFreq,
                        max: StopFreq,
                        suggestedMin: StartFreq,
                        suggestedMax: StopFreq,
                        stepSize: 0.25,
                    }
                }],

                yAxes: [{
                    ticks: {
                        min:0,
                        max:10,
                        suggestedMin: 0,
                        suggestedMax: 10,
                        maxTicksLimit: 11,
                        stepSize : 1,
                        beginAtZero: true,
                    }
                }]
            }

        }
    });
}



function generateChart() {
   // removeData(chart);
    let data = getdata();
    draw_chart(data);
}

HTML

<table class="inner">
        <tr class="inner">
          <td class="inner"> Attenuation (air) /</td>
          <td class="inner"> <input class="numInput" type="number" id="unitInch"/></td>
          <td class="inner">(in inches)</td>

        </tr>
        <tr class="inner">
          <td class="inner" colspan="2">Rectangular WG</td>
          <td class="inner">Circular WG</td>
          <td class="inner">Material</td>
        </tr>
        <tr class="inner">
          <td class="inner">a (inch)</td>
          <td class="inner">b (inch)</td>
          <td class="inner">Diameter (inch)</td>
          <td class="inner">Conductivity ( x 10<sup>7</sup> S/m)</td>
          <td class="inner">Start Freq (GHz)</td>
          <td class="inner">Stop Freq (GHz)</td>
        </tr>
        <tr class="inner">
          <td class="inner"><input class="numInput" type="number" id='a'/></td>
          <td class="inner"><input class="numInput" type="number" id="b"/></td>
          <td class="inner"><input class="numInput" type="number" id="Diameter"/></td>
          <td class="inner"><input class="numInput" type="number" id="Conductivity"/></td>
          <td class="inner"><input class="numInput" type="number" id="StartFreq"/></td>
          <td class="inner"><input class="numInput" type="number" id="StopFreq"/></td>

        </tr>
      </table>

  <button onclick="generateChart()"><strong>Generate Chart</strong></button>
<div id="chartsize">
      <canvas id="myChart"></canvas>
</div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js"></script>
      <script src="js/chart.js"></script>

** Кстати, моя диаграмма работает совершенно нормально при первой загрузке страницы,затем, когда я обновляюсь, график зависает как сумасшедший при зависании. Я добавил намного больше кода, чтобы вы, ребята, могли воссоздать диаграмму и выяснить ее. Пожалуйста, игнорируйте плохой стиль, я новичок в веб-разработке ... **

1 Ответ

1 голос
/ 08 октября 2019

Это, кажется, довольно распространенная проблема с Chart.js. Типичные предлагаемые решения - либо уничтожить экземпляр chart, либо удалить элемент canvas и создать новый при каждом обновлении диаграммы.

Для первого возможного решения вы можете попробовать вызвать destroy() на вашем объекте диаграммы. Например, если ваш объект диаграммы chart, вы можете вызвать chart.destroy();. Из документации :

Используйте это для уничтожения любых созданных экземпляров диаграммы. Это очистит все ссылки, хранящиеся в объекте диаграммы в Chart.js, вместе со всеми связанными прослушивателями событий, присоединенными Chart.js. Это необходимо вызвать до повторного использования холста для нового графика.

Однако это не всегда работает. Удаление и создание элемента canvas, похоже, сработало, когда я протестировал его с вашим кодом. Вы можете использовать функцию, подобную приведенной ниже, и вызывать ее всякий раз, когда нажимаете кнопку «Создать диаграмму»:

function resetCanvas (){
  $("canvas").remove();
  $("#chartsize").append('<canvas id="myChart"><canvas>');
  canvas = document.querySelector("#myChart");
  ctx = canvas.getContext("2d");
};

Обратите внимание, что вам может потребоваться установить высоту и ширину контейнера диаграммы. Я использую jQuery для этой функции для простоты. Но вы могли бы воспроизвести его, используя vanilla JS, если это необходимо.

См. Пример здесь, используя ваш код: https://jsfiddle.net/fL1rd3wp/1/

...