Old data flickering after hover on line graph Chart.js - javascript

My problem is not making the chart, but when I input new values for the start freq and end freq, which are the first and last values of my x-axis array after calling getFreq(), the chart glitches when I hover, going back and forth between the old data and new data. Can anyone help me figure out how to delete the old data and make/update to a new chart where the chart doesn't flicker? My code is shown below.
If you want to test the graph
put 39.4 as attenuation, 0.1 as a, 0.05 as b, 0.16 for diameter, 15 for conductivity, and 25 and 125 as the start and end freq respectively. To test the flickering, just replace 25 with another number and hover over the graph.
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>
By the way, my chart works completely fine the first time I load the page, then when I update, the chart flickers like crazy when hovering. I added in a lot more code, so that you guys can recreate the chart and figure it out. Please ignore the bad style, I am new to Web Development...

It is because chartjs doesn't redraw the chart, it creates a new one over the old one. You have to make a reset function that gets called before the new chart is drawn

Related

How to run jQuery before loading page or how can call back "getJson(function(data))"?

I'm trying to create a chart that can be filtered by selecting the date with the data I got from the JSON file.
I get default data for chart from JSON file before date filtering.I have output in the log, but I can't display it (default data) in the chart.
I noticed that it was caused by running chart before entering the getJson(function(data){}) function. How can I fix it ?
$.getJSON('LS22731.json', function(data)
{ /* POWER ON TIME*/
data.forEach(function(item) {
data_power = item['PowerOnTime'];
dtarr.push(data_power);
label = item.CratedAt;
lbarr.push(label);
});
var len = dtarr.length;
var lastvalue = new Date(dtarr[len - 1]);
var PowerOnTime = moment(lastvalue).format('YYYY-MM-DD h:mm');
OnTime = moment(PowerOnTime).format('h:mm:ss');
document.getElementById("pot").innerHTML = OnTime;
dateTime = lastvalue.toDateString();
document.getElementById("pod").innerHTML = dateTime;
/* ******************************************************************************* */
/* GET DATA FROM JSON */
var len = data.length;
for (i = 0; i < len; i++) {
datatime = data[i]['CratedAt'];
data_time.push(datatime);
dataenergy = data[i]['Energy (J)'];
data_energy.push(dataenergy);
datavolt1 = data[i]['V1 (Volts)'];
akim1 = Math.abs(data[i]['I1 (Ampers)']);
power1 = datavolt1 * akim1 * 1000;
data_phase1.push(power1);
datavolt2 = data[i]['V2 (Volts)'];
akim2 = Math.abs(data[i]['I2 (Ampers)']);
power2 = datavolt2 * akim2 * 1000;
data_phase2.push(power2);
datavolt3 = data[i]['V3 (Volts)'];
akim3 = Math.abs(data[i]['I3 (Ampers)']);
power3 = datavolt3 * akim3 * 1000;
data_phase3.push(power3);
}
/* ******************************************************** */
/*CHANGE DATA FORMAT */
var last_time = data_time[len - 1];
/*console.log(lastvalue);*/
var y_date = new Date(last_time);
var y_date_label = y_date.setHours(y_date.getHours() - 1);
var datelabel = new Date(y_date_label);
var start_time = moment(datelabel).format('YYYY-MM-DD h:mm');
data_time.forEach(function(item) {
form = moment(item).format('YYYY-MM-DD h:mm');
date_label.push(form);
});
console.log(date_label);
var startindex = date_label.indexOf(start_time);
var lastindex = date_label.indexOf(last_time);
date_arr = date_label.slice(startindex, lastindex);
data_arr = data_energy.slice(startindex, lastindex);
phase_1 = data_phase1.slice(startindex, lastindex);
phase_2 = data_phase2.slice(startindex, lastindex);
phase_3 = data_phase3.slice(startindex, lastindex);
console.log(date_arr);
date_arr.forEach(function(item) {
label = moment(item).format("DD/MM, h:mm");
chart_label.push(label);
});
console.log(chart_label);
});
....
...
....
<div class="col-6 col-m-12 col-sm-12">
<div class="card-large">
<div class="card-header">
<center>
<div class="container" style="width:500px; height:500px;">
<input type="datetime-local" id="start" name="startdate">
<input type="datetime-local" id="end" name="lastdate">
<button onclick="changeData();">Search </button>
<canvas id="myChart"></canvas>
</div>
</center>
</div>
</div>
</div>
<div class="col-6 col-m-12 col-sm-12">
<div class="card-large">
<div class="card-header">
<center>
<div class="container" style="width:550px; height:200px;">
<input type="datetime-local" id="start_power" name="startdate">
<input type="datetime-local" id="end_power" name="lastdate">
<button onclick="change_DataPower();">Search </button>
<canvas id="my_Chart"></canvas>
</div>
</center>
</div>
</div>
</div>
....
.....
......
<script>
const changeData = () => {
var get_start = document.getElementById("start").value;
var get_end = document.getElementById("end").value;
var startDate = moment(get_start).format('YYYY-MM-DD h:mm');
console.log(startDate);
var endDate = moment(get_end).format('YYYY-MM-DD h:mm');
console.log(endDate);
var startindex = date_label.indexOf(startDate);
console.log(startindex);
var lastindex = date_label.indexOf(endDate);
console.log(lastindex);
var datearr = date_label.slice(startindex, lastindex);
console.log(datearr);
var dataarr = data_energy.slice(startindex, lastindex);
console.log(dataarr);
myChart.data.datasets[0].data = dataarr;
myChart.data.labels = datearr;
myChart.update();
};
var ctx = document.getElementById('myChart').getContext('2d');
console.log("payar");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: chart_label,
datasets: [{
backgroundColor: 'rgb(129, 198, 2228)',
borderColor: '#959DA6',
data: data_energy,
label: 'Energy (J)',
fill: false,
pointRadius: 0
}]
},
options: {
legend: {
labels: {
fontColor: '#959DA6'
}
},
title: {
display: true,
text: "1 Saatlik Enerji Tüketimi",
fontColor: "#959DA6",
},
responsive: 'true',
scales: {
yAxes: [{
gridLines: {
display: false
},
ticks: {
fontColor: "#959DA6"
}
}],
xAxes: [{
gridLines: {
display: false
},
ticks: {
fontColor: "#959DA6",
autoSkip: true,
maxTicksLimit: 6,
}
}]
}
}
});
You can keep the button disabled and only enable it after receiving the data.
<button id="search" onclick="changeData();" disabled>Search </button>
and
$('#search').prop('disabled', false);
at the end of your $.getJSON() callback;

passing a value to a variable JS

I am trying to draw a graph based on a calculator and the result of the equation is used as one of the axis in this case Y in order to make the first point and the second input file is for X axis but I can't manage to take the result into the next function. any recommendations or approach?
Here is the JS
function parseCalculationString(s) {
var calculation = [],
current = '';
for (var i = 0, ch; ch = s.charAt(i); i++) {
if ('^*/+-'.indexOf(ch) > -1) {
if (current == '' && ch == '-') {
current = '-';
} else {
calculation.push(parseFloat(current), ch);
current = '';
}
} else {
current += s.charAt(i);
}
}
if (current != '') {
calculation.push(parseFloat(current));
}
return calculation;
}
function removeBrackets(s) {
let regEx = /\((.*?)\)/g;
let ops = s.match(regEx);
for (var i = 0; i < ops.length; i++) {
let op = ops[i];
let res = calculate(parseCalculationString(op.replace('(', '').replace(')', '')));
s = s.replace(op, res);
}
return s;
}
function calculate(calc) {
var ops = [
{
'^': function(a, b) {
return Math.pow(a, b);
}
}, {
'*': function(a, b) {
return a * b
},
'/': function(a, b) {
return a / b
},
}, {
'+': function(a, b) {
return a + b
},
'-': function(a, b) {
return a - b
}
}],
newCalc = [],
currentOp;
for (var i = 0; i < ops.length; i++) {
for (var j = 0; j < calc.length; j++) {
if (ops[i][calc[j]]) {
currentOp = ops[i][calc[j]];
} else if (currentOp) {
newCalc[newCalc.length - 1] = currentOp(newCalc[newCalc.length - 1], calc[j]);
currentOp = null;
} else {
newCalc.push(calc[j]);
}
console.log(newCalc);
}
calc = newCalc;
newCalc = [];
}
if (calc.length > 1) {
console.log('Error: no funciona');
return calc;
} else {
return calc[0];
}
}
var calculateButton = document.getElementById('calculate'),
userInput = document.getElementById('userInput'),
sustuir = document.getElementById('userInputX'),
result = document.getElementById('result');
calculateButton.addEventListener('click', function() {
result.innerHTML = "la respuesta de Y " + calculate(
parseCalculationString(removeBrackets(
(userInput.value)
))
);
return calculateButton;
});
window.onload = function() {
var dps = []; //dataPoints.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Result"
},
data: [{
type: "line",
dataPoints: dps
}]
});
function addDataPointsAndRender() {
xValue = Number(document.getElementById("result").value);
yValue = Number(document.getElementById("userInputX").value);
dps.push({
x: xValue,
y: yValue
});
chart.render();
}
var renderButton = document.getElementById("calculate");
renderButton.addEventListener("click", addDataPointsAndRender);
}
here is the HTMl
<div class="container">
<h1>Test Part 1 </h1>
<p>Example 2x*(2+2) use * in input before parentheses in order to work properly.</p>
<input type="text" id="userInput" />
<input type="text" id="userInputX" />
<input type="button" value="Calculate" id="calculate" />
<div id="result"></div>
<div id="chartContainer" style="height: 270px; width: 100%;"></div>
</div>
thanks in advance

JSXgraph not moving points when I change a function

I'm using JSXgraph to show students limsups and liminfs. The version works here - http://ibldynamics.com/exercises/ex2_56.html
Here's the code:
<div style="width: 500px; height: 40px;">
<p style="display: inline;">N:</p>
// Create a slider for the values of N
<input id="NSlider" type="range" min="1" max="19" value="1" step="1" style="width: 50%;">
<p style="display: inline;"><span id="NOut"></span></p>
<script>
// Get the value of N from the slider
var NSlider = document.getElementById("NSlider");
var NOutput = document.getElementById("NOut");
NOutput.innerHTML = NSlider.value; // Output value for student to see
</script>
</div>
<!-- Create board with points -->
<div id="box" class="jxgbox" style="width:500px; height:500px;">
<script type="text/javascript">
// Create board
var board = JXG.JSXGraph.initBoard('box', {
boundingbox: [-1, 2, 21, -0.2],
axis: true,
grid: true
});
// Generate points in the sequence and graph points of the sequence
var i;
var s = [null];
for (i = 1; i <= 20; i++) {
s.push(1 + Math.pow(-1, i) / i);
board.create('point', [i, s[i]], {
color: 'yellow',
fixed: true,
withLabel: false
});
}
// Genereate liminfs and limsups
var infs = [null],
sups = [null];
for (i = 1; i <= 20; i++) {
infs.push(Math.min.apply(null, s.slice(i + 1)));
sups.push(Math.max.apply(null, s.slice(i + 1)));
}
// Graph liminf and limsup points
var liminf = board.create('point', [
function() { return NSlider.value; },
function() { return infs[NSlider.value]; }], {
color: 'blue',
withLabel: false
});
var limsup = board.create('point', [
function() { return NSlider.value; },
function() { return sups[NSlider.value]; }], {
color: 'orange',
withLabel: false
});
board.update()
</script>
</div>
<script>
// Set board to update when the N slider is updated
NSlider.oninput = function () {
NOutput.innerHTML = this.value; // Output value for student to see
liminf.moveTo([NSlider.value, infs[NSlider.value]]);
limsup.moveTo([NSlider.value, sups[NSlider.value]]);
}
</script>
The problem is the version I have here - http://ibldynamics.com/exercises/ex2_57.html
I've only changed two things. The function that I use to generate the points is s.push((-1)**i*(1 + (1 / i))); and the bounding box is a little bigger. For some reason the blue points won't show up any more.
Any ideas?

VueJs renders all elements upon a single change

I have the following sample grid in which I push some new values to the bound list.
Press anywhere in the grid to push a new value to the grid.
As you can see in the fiddle, the updated cell will have a green color for 500 ms, and all the re-rendered elements will have yellow color.
The question is how we should configure Vue component so that it only re-render the changed element instead of them all?
If you look at the fiddle console output, you will see numbers like (13001, 26001, ...) and this equals to the number of all cells (1000 rows x 13 columns).
.yellow {
background-color: yellow;
}
.pushed {
background-color: lightgreen
}
<script src="https://unpkg.com/vue">
var globalCount = 0;
</script>
<head>
<title>Vue Render Performance</title>
</head>
<div id="demo">
<demo-grid :data="gridData" :columns="gridColumns"> </demo-grid>
</div>
<script type="text/x-template" id="grid-template">
<table #click="pushData()">
<thead>
<tr>
<th v-for="key in columns">
{{key}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(entry, i) in data">
<td v-for="(key, j) in columns" :id="'a'+i +'_'+j">
{{renderMe(entry[key], 'a'+i +'_'+j)}}
</td>
</tr>
</tbody>
</table>
</script>
<script>
const data = newData(1000);
var renderedCount = 0;
var startTime = performance.now();
Vue.component('demo-grid', {
props: {
data: Array,
columns: Array,
renderCount: Object,
},
template: '#grid-template',
methods: {
renderMe(el, id) {
const elm = document.getElementById(id);
if (elm) {
elm.className += " yellow";
}
if (!renderedCount) {
renderedCount = 0
} else {
renderedCount++;
}
return el;
},
pushData() {
debugger
var push = function() {
let cols = ["Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8", "Col9", "Col10", "Col11", "Col12", "Col13"];
var t0 = performance.now();
for (let i = 0; i < 1; i++) {
let newVal = Math.random() * 10000,
row = Math.round(Math.random() * 1000),
cellIndex = Math.floor(Math.random() * cols.length);
cell = cols[cellIndex];
if (data[row])
data[row][cell] = newVal;
var el = document.querySelector('tbody tr:nth-child(' + row + ') td:nth-child(' +
cellIndex +
')');
if (el) {
el.className = 'pushed';
el.scrollIntoView();
var t = function() {
if (el) {
el.className = '';
}
clearTimeout(t);
};
setTimeout(t, 500);
}
console.log('pushed to cell [' + row + ',' + cellIndex + '] :' + newVal);
console.log('Rendered Count: ' + renderedCount)
renderedCount++;
};
var t1 = performance.now();
console.log(t1 - t0)
};
push();
}
}
});
// bootstrap the demo
var demo = new Vue({
el: '#demo',
data: {
searchQuery: '',
gridColumns: ["Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8", "Col9", "Col10", "Col11", "Col12", "Col13"],
gridData: data
}
})
Vue.config.devtools = true;
function newData(count) {
const data = [];
for (let i = 0; i < count; i++) {
data.push({
Col1: "Record",
Col2: 818959475,
Col3: 467587749,
Col4: 438,
Col5: 439,
Col6: 440,
Col7: 2.1,
Col8: 436.2,
Col9: 2.4,
Col10: 5770,
Col11: 5771,
Col12: 5772,
Col13: 5773
});
}
return data;
}
</script>
When you don't want to re-render and entire list of information, the typical way to handle it is to push the things that need to re-render into a component. Here is an updated version of your code that pushes the rows into a component and renders a fraction of what you were doing before.
Vue.component("demo-row", {
props:["entry", "columns", "rowIndex"],
template:`
<tr>
<td v-for="(key, j) in columns" :id="'a'+rowIndex +'_'+j">
{{renderMe(entry[key], 'a'+rowIndex +'_'+j)}}
</td>
</tr>
`,
methods:{
renderMe(el, id) {
const elm = document.getElementById(id);
if (elm) {
elm.className += " yellow";
}
if (!renderedCount) {
renderedCount = 0
} else {
renderedCount++;
}
return el;
},
}
})
Vue.component('demo-grid', {
props: {
items: Array,
columns: Array
},
template: '#grid-template',
methods: {
pushData() {
this.$parent.pushData(this.$parent.gridItems, this.$parent.gridColumns);
}
}
});
Example codepen.
Note, I did not change anything else that you are doing that could probably be done more idiomatically in Vue, I just wanted to demonstrate that there is no need for everything to re-render.

Computed value not updating on changing text box value in knockout javascript

http://jsfiddle.net/Kapil_B/vz3r0bs3/9/
In this fiddle I am trying to update the formattedPrice2 value on changing the rates in the textbox.I am able to get the updated price but the price1 is not getting updated value.
Can you please tell me the reason why the price1 value is not getting updated? That is why formattedPrice2 is not getting updated.
<select data-bind="options: $root.newLot, value: dropdownAValue, optionsText: 'type'"></select>
<table align="left">
<thead>
<tr align="left">
<th width="10%">Pair</th>
<th width="10%">Rate</th>
<th width="10%">formattedPrice2</th>
</tr>
</thead>
<!-- Todo: Generate table body -->
<tbody data-bind="foreach:curArray">
<tr>
<td data-bind="text: rate().pair"></td>
<td> <input data-bind="value: myQuote, valueUpdate:'afterkeydown'" />
</td>
<td data-bind="text: formattedPrice2"></td>
</tr>
</tbody>
</table>
// Class to represent a row in the price calculation grid
function PriceCalculation(rate, myQuote, newPairs, nl, currentlotvalue) {
var self = this;
self.rate = ko.observable(rate);
self.newPairs = newPairs;
self.nl = ko.observable(nl);
self.myQuote = ko.observable(myQuote);
self.currentlotvalue = currentlotvalue;
self.leverage = self.rate().leverage;
self.formattedPrice2 = ko.computed(function () {
var cur = self.rate().pair;
//var price = self.rate().price;
var price = self.myQuote();
var pip = 1;
var lot1 = self.currentlotvalue;
var JPlot = lot1 * 100;
if (cur.indexOf("/USD") > -1) {
pip = lot1;
} else if (cur.indexOf("/JPY") > -1) {
pip = JPlot / price;
} else if (cur.indexOf("USD/") > -1) {
pip = lot1 / price;
} else {
var base = cur.split("/")[0];
var counter = cur.split("/")[1];
for (var i = 0; i < self.newPairs.length; i++) {
var base1 = self.newPairs[i].pair.split("/")[0];
var counter1 = self.newPairs[i].pair.split("/")[1];
var price1 = self.newPairs[i].price;
alert(price1);
if (base1 == "USD") {
if ((self.newPairs[i].pair) == ("USD/" + counter)) {
pip = lot1 / price1;
}
} else if (counter1 == "USD") {
if ((self.newPairs[i].pair) == (counter + "/USD")) {
pip = lot1 * price1;
}
}
}
}
//alert(pip? "$" + pip.toFixed(2): "None");
return pip ? "$" + pip.toFixed(2) : "None";
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
self.curArray = ko.observableArray([]);
self.rates = ko.observableArray([]);
// Non-editable catalog data - would come from the server
self.rates = [ {
pair: "EUR/HUF",
price: 318.815,
leverage: "20:1*"
}, {
pair: "USD/HUF",
price: 265.13,
leverage: "20:1*"
}, {
pair: "XAG/USD",
price: 15.734,
leverage: "1:1*"
}, {
pair: "XAU/USD",
price: 1184.43,
leverage: "1:1*"
}];
self.newLot = [{
type: "Micro",
lotSize: 0.1
}, {
type: "Mini",
lotSize: 1
}, {
type: "Standard",
lotSize: 10
}];
self.newlots = ko.observableArray(self.newLot);
self.dropdownAValue = ko.observable(self.newlots);
var currentlotvalue = 0.1;
self.dropdownAValue.subscribe(function () {
if (self.dropdownAValue().type == "Micro") {
//alert("Micro");
currentlotvalue = 0.1;
} else if (self.dropdownAValue().type == "Mini") {
//alert("Mini");
currentlotvalue = 1;
} else if (self.dropdownAValue().type == "Standard") {
//alert("Standard");
currentlotvalue = 10;
}
var newItems = ko.utils.arrayMap(self.rates, function (item) {
return new PriceCalculation(item, item.price, self.rates, self.newLot[0], currentlotvalue)
});
self.curArray(newItems);
},this, "change");
}
ko.applyBindings(new ReservationsViewModel());

Categories