JSXgraph not moving points when I change a function - javascript

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?

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;

Updating graph based on input range

This forum always provided quick and good comments on different coding problems.
Today I want your help! Please!
I have a project in HTML and I want to add some features. I have to create a graph based on a function (f(x_r)). This function will depend on two parameters, x1 and x2.
I want that these 2 parameters to be from the input range (E_sursa and r_intern).
I've tried different methods, but I was not able to make for example x1 or x2 a parameter or a constant (from the function citire). I also try some old methods presented in this forum, but they did not work.
Sorry some words from the code are in Romanian.
The goal:
"var x1=1; var x2=1;" to update their values based on (E_sursa and r_intern or )
x1 from the function citire to be used in the first sript (this one with var x1=1;)
Edit
how could i replace var x1; with the value from var
'x1 = document.getElementById("r_sursa").value;'
I try to read it as a parameter ( to call a function), but it did not worked:
'function Resis() { return document.getElementById("r_sursa").value;} var x1=Resis();'
<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
zoomEnabled: true,
title:{
text: "power"
},
axisY :{
includeZero:false
},
data: data // random generator below
});
chart.render();
}
var limit = 100;
var x1=1;
var x2=1;
var y = 0;
var data = [];
var dataSeries = { type: "line" };
var dataPoints = [];
for (var i = 0; i < limit; i += 1)
{ x_r = i/10;
y = x2*x2*x_r/((parseFloat(x1)+x_r)*(parseFloat(x1)+x_r));
dataPoints.push({
x: x_r,
y: y
});
}
dataSeries.dataPoints = dataPoints;
data.push(dataSeries);
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script></head>
<body>
<div id="chartContainer" style="height: 370px; width: 50%;">
</div>
<label for="r_sursa">resistance</label>
<input type="range" id="r_sursa" name="r_sursa" min="0" max="10" step="0.1">
<b id="demo1"></b>
<br>
<label for="E_sursa">voltage</label>
<input type="range" id="E_sursa" name="E_sursa" min="0" max="12" step="0.1">
<b id="demo2"></b>
<br>
<label for="R_sarcina">ohms</label>
<input type="range" id="R_sarcina" name="R_sarcina" min="0" max="10" step="0.1">
<b id="demo3"></b>
<br>
amps
<b id="demo4"></b>
<br>
power
<b id="demo5"></b>
<br>
<script>
function citire() {
var x1 = document.getElementById("r_sursa").value;
var x2 = document.getElementById("E_sursa").value;
var x3 = document.getElementById("R_sarcina").value;
var curent, putere;
y=parseFloat(x1)+parseFloat(x3);
curent = x2/(parseFloat(x1)+parseFloat(x3));
putere = x2*x2*x3/((parseFloat(x1)+parseFloat(x3))*(parseFloat(x1)+parseFloat(x3)));
document.getElementById("demo1").innerHTML = x1 + " Ω";
document.getElementById("demo2").innerHTML = x2 + " V";
document.getElementById("demo3").innerHTML = x3 + " Ω";
document.getElementById("demo4").innerHTML = curent.toFixed(2)+ " A";
document.getElementById("demo5").innerHTML = putere.toFixed(2)+ " W";
}
setInterval(function() { citire(); },0);
</script>
</body>
</html>
You should reassign the data attribute of the chart object and then invoke the render() method every time you have a new dataset.
For your needs of assigning x1 to the slider's value right at the load time, you can easily figure it yourself by reading my sample code below.
<!DOCTYPE HTML>
<html>
<head>
<script>
var limit = 100;
var chart;
function getData() {
var x1 = parseFloat(document.getElementById("r_sursa").value);
var x2 = 1;
var y = 0;
var data = [];
var dataSeries = {
type: "line"
};
var dataPoints = [];
for (var i = 0; i < limit; i += 1) {
x_r = i / 10;
y = x2 * x2 * x_r / ((parseFloat(x1) + x_r) * (parseFloat(x1) + x_r));
dataPoints.push({
x: x_r,
y: y
});
}
dataSeries.dataPoints = dataPoints;
data.push(dataSeries);
return data
}
window.onload = function() {
chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
zoomEnabled: true,
title: {
text: "power"
},
axisY: {
includeZero: false
},
data: getData() // random generator below
});
chart.render();
}
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 50%;">
</div>
<label for="r_sursa">resistance</label>
<input type="range" id="r_sursa" name="r_sursa" min="0" max="10" step="0.1">
<b id="demo1"></b>
<br>
<label for="E_sursa">voltage</label>
<input type="range" id="E_sursa" name="E_sursa" min="0" max="12" step="0.1">
<b id="demo2"></b>
<br>
<label for="R_sarcina">ohms</label>
<input type="range" id="R_sarcina" name="R_sarcina" min="0" max="10" step="0.1">
<b id="demo3"></b>
<br>
amps
<b id="demo4"></b>
<br>
power
<b id="demo5"></b>
<br>
<script>
function citire() {
var x1 = document.getElementById("r_sursa").value;
var x2 = document.getElementById("E_sursa").value;
var x3 = document.getElementById("R_sarcina").value;
var curent, putere;
y = parseFloat(x1) + parseFloat(x3);
curent = x2 / (parseFloat(x1) + parseFloat(x3));
putere = x2 * x2 * x3 / ((parseFloat(x1) + parseFloat(x3)) * (parseFloat(x1) + parseFloat(x3)));
document.getElementById("demo1").innerHTML = x1 + " Ω";
document.getElementById("demo2").innerHTML = x2 + " V";
document.getElementById("demo3").innerHTML = x3 + " Ω";
document.getElementById("demo4").innerHTML = curent.toFixed(2) + " A";
document.getElementById("demo5").innerHTML = putere.toFixed(2) + " W";
chart.options.data = getData();
chart.render()
}
setInterval(function() {
citire();
}, 0);
</script>
</body>
</html>

Old data flickering after hover on line graph Chart.js

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

How do I take text from the text box and use it to implement it in this code?

I'm practicing javascript and learning on my own. I am creating a game where you enter a text coordinates and the game tells you whether you dug something up or not. But I am trying to implement a text box so you can play out of a browser instead of the command prompt, but I'm having trouble getting the game to take the text and then run the code using it when you click on the button.
Here is the HTML for the game.
<head>
<meta charset="UTF-8">
<title>Game Board</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="board.js"></script>
<script type="text/javascript" src="game.js"></script>
</head>
<body>
<center>
<h1>Archaeology Board</h1>
Palace = 5 Spaces </br>
Temple = 4 Spaces </br>
Forum = 4 Spaces </br>
House = 3 Spaces </br>
Hut = 2 Spaces </br>
<h3>
<table id="board">
</table>
</h3>
<p>
<label for="DigBox">Enter dig coordinates:</label>
<input type="text" id="DigBox" size="3" value="" />
<input type="button" value="Dig" id="run" />
</p>
<p><input type="button" value="Restart Game" id="restart" /></p>
</center>
</body>
</html>
This is the js file to create the board.
function GameBoard()
{
this.ruins = [
{
name: "Palace",
size: 5,
successes: 0
},
{
name: "Temple",
size: 4,
successes: 0
},
{
name: "Forum",
size: 4,
successes: 0
},
{
name: "House",
size: 3,
successes: 0
},
{
name: "Hut",
size: 2,
successes: 0
}
];
this.rows = ["a", "b", "c", "d", "e", "f", "g", "h"];
this.columns = ["1", "2", "3", "4", "5", "6", "7", "8"];
this.cellMarker = 'X';
}
GameBoard.prototype.setBoard = function ()
{
var i, j, boardTags;
boardTags = "";
// build the first row of column labels
boardTags += "<tr><th>&nbsp</th>";
for (j = 0; j < this.columns.length; j++) {
boardTags += "<th>" + this.columns[j] + "</th>";
}
boardTags += "</tr>";
// build the table with HTML tags
for (i = 0; i < this.rows.length; i++) {
boardTags += "<tr>";
boardTags += "<th>" + this.rows[i] + "</th>"; // row labels
for (j = 0; j < this.columns.length; j++) {
boardTags += "<td class='square' id='cell" +
this.rows[i] + this.columns[j] + "'>" + this.cellMarker + "</ td>";
}
boardTags += "</tr>";
}
$("#board").html(boardTags);
for (i = 0; i < this.ruins.length; i++) {
this.setRuin(this.ruins[i]);
}
}
GameBoard.prototype.dig = function(square, processResult)
{
var target, targetObj;
target = $("#cell"+square).attr('ruin');
if (target) {
targetObj = this.getRuin(target);
if (! $("#cell"+square).attr('dug')) {
$("#cell"+square).attr('dug', 'yes');
targetObj.successes++;
}
return targetObj;
}
else {
return undefined;
}
}
GameBoard.prototype.getRuin = function(ruinName)
{
for (var i = 0; i < this.ruins.length; i++) {
if (ruinName === this.ruins[i].name) {
return this.ruins[i];
}
}
return undefined;
}
GameBoard.prototype.randomSquare = function()
{
var colIndex = Math.floor(Math.random() * this.columns.length);
var rowIndex = Math.floor(Math.random() * this.rows.length);
return this.rows[rowIndex] + this.columns[colIndex];
}
GameBoard.prototype.setRuin = function(ruin)
{
// keeps randomly trying to place a ruin until it fits on the board
var candidateSquare = this.randomSquare();
var across = Math.random() < 0.5;
var success = this.tryPlacement(ruin, candidateSquare, across, ruin.size);
while (! success) {
candidateSquare = this.randomSquare();
across = Math.random() < 0.5;
success = this.tryPlacement(ruin, candidateSquare, across, ruin.size);
}
}
GameBoard.prototype.tryPlacement = function(ruin, square, across, size) {
var nextSquare;
if (size === 0) {
// ruin fits!
return true;
}
else if (! square) {
// invalid square
return false;
}
if (! $("#cell" + square).attr('ruin')) {
$("#cell" + square).attr('ruin', ruin.name);
// see if the rest of the ruin fits
if (this.tryPlacement(ruin, this.increment(square, across), across, size - 1)) {
// ruin fits!
return true;
}
else {
// ruin didn't fit --- undo occupied square and return false
$("#cell" + square).removeAttr('ruin');
return false
}
}
}
GameBoard.prototype.increment = function(square, across)
{
if (across) {
// need to increment the column dimension if possible
var colIndex = this.columns.indexOf(square.charAt(1));
colIndex++;
if (colIndex === this.columns.length) {
return undefined;
}
else {
return square.charAt(0) + this.columns[colIndex];
}
}
else {
// need to increment the row dimension if possible
var rowIndex = this.rows.indexOf(square.charAt(0));
rowIndex++;
if (rowIndex === this.rows.length) {
return undefined;
}
else {
return this.rows[rowIndex] + square.charAt(1);
}
}
}
This is the code I'm trying to implement in
$(function () {
tryDig = function(targetCell)
{
var targetObj = board.dig(targetCell);
if (targetObj) {
alert('Success finding the ' + targetObj.name);
$("#cell"+targetCell).html('#');
$("#cell"+targetCell).css('color', 'blue');
}
else {
alert('Failure!');
$("#cell"+targetCell).html('*').css('color', 'red');
}
}
board = new GameBoard();
board.setBoard();
});
initialize = function() {
$("#run").click(tryDig);
}
initialize = function() {
$("#restart").click(GameBoard.prototype.setBoard);
}
$(initialize);
I want to make it so whatever is in the text box, the game uses that as the coordinates to dig up in the board.

Filtering items with angular js

I have an array of items in form of service - as I know it's like proper way to keep data you use in different controllers.I watched tutorial and did the filtering by brands. But I have an obstacle with filtering of my Items by another parameters, such as price, length and frequency... So I have made sliders by another example but I have no idea how to tie up it with my array of Items. Please do me a favour, show how to tie up even one of my parameters, price for example.
http://angular.zxcvbn.ru
services.js:
myApp.service('ProductDataService', function() {
//sample data
var items = [
{ name:'Picachoo', id:1, price:25000, pict:'http://www.metrord.do/_internal/gxml!0/2qijkhn0ctpwx8acoz5fxkpvtmr4nbh$r05jcw5nnz5dt1u7odn7q01jm5k3ezo/screen-shot-2016-07-24-at-11-55-41-am.jpeg', len: 250, friq: 5000, brand: 'came' },
{ name:'Tortule', id:2, price:30000, pict:'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcR2APj6_uBfhHRXLn1dZN58ZocpzMxGMFLZmuqHEU5SybKN4QAVfg', len: 250, friq: 300, brand: 'came' },
{ name:'Dragon', id:3, price:33500, pict:'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcSJotIxkjgXgm9m3m-0FuUxN6g9fGGXmP84VDRrPZoWa-x8Dqqd', len: 350, friq: 300, brand: 'came' },
{ name:'encrypted1', id:4, price:45000, pict:'http://gaidi.ru/wp-content/uploads/2016/07/kak-pravilno-lovit-pokemonov-v-pokemon-go.jpg', len: 400, friq: 3000, brand: 'came' },
{ name:'pravilno', id:5, price:48600, pict:'http://vignette3.wikia.nocookie.net/pokemon/images/2/2e/009Blastoise_Dream.png/revision/latest?cb=20140812050618', len: 550, friq: 2000, brand: 'came' },
{ name:'images', id:6, price:30000, pict:'https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSqywi0lMtmf1sAR-20rg0HXETMueY3H71iJP35WsdsPHGVokK41g', len: 550, friq: 1000, brand: 'bft' },
{ name:'Foxy', id:7, price:38000, pict:'http://vgtimes.ru/uploads/posts/2016-07/1468938437_pk_vulpix.png', len: 350, friq: 10000, brand: 'bft' },
{ name:'Pteradactys', id:8, price:43000, pict:'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRJBXypwhl8-z4IsAZokgQlqPx_vZymtENBdlPy1HhN34uODEZ5', len: 800, friq: 10000, brand: 'bft' },
{ name:'encrypted', id:9, price:35800, pict:'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQZNKoA9LMtQHhgU4Toy7xXfzGEp6Rb4Kv6I16RgMjWO0Dnb36EFA', len: 1200, friq: 3000, brand: 'faac' },
{ name:'Jidjfj', id:10, price:14000, pict:'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPBKrRLvhYm9y-LxwRM4Qc_psMjd_luij_04ChmmQjcrdxgmcG3w', len: 800, friq: 5000, brand: 'fors' }
];
brands = {came : true, bft : true, faac : true, fors : true} ;
this.getItems = function() {
return items;
};
this.getBrands = function() {
return brands;
};
this.maxPrice = function() {
var max;
var producto;
for(var i = 0; i < items.length-1; i++) {
for(var j = 0; j < items.length-i-1; j++){
if (producto[j] > producto[j+1]) {
max = producto[j];
producto[j] = producto[j+1];
producto[j+1] = b;
}
}
}
return max;
}
this.minPrice = function() {
var min;
var producto;
for(var i = 0; i < items.length-1; i++) {
for(var j = 0; j < items.length-i-1; j++){
if (producto[j] < producto[j+1]) {
min = producto[j];
producto[j] = producto[j+1];
producto[j+1] = b;
}
}
}
return min;
}
});
slider_price.js:
myApp.controller('priceCtrl', function($scope, ProductDataService) {
$scope.search = { price_min : '', price_max : '', amount_min : 14000, amount_max : 48600 };
});
/* Range Slider
Input with default values:
-min=0 // Min slider value
-max=100 // Max slider value
-step=1 // Steps
Output / Input model
-value-min // Default value #min
-value-max // Default value #max
example:
<slider-range min="0" max="100" step="5" value-min="scope.form.slider_value_min" value-max="scope.form.slider_value_max"></slider-range>
*/
myApp.directive('priceRange', ['$document',function($document) {
// Move slider handle and range line
var moveHandle = function(handle, elem, posX) {
$(elem).find('.handle.'+handle).css("left",posX +'%');
};
var moveRange = function(elem,posMin,posMax) {
$(elem).find('.range').css("left",posMin +'%');
$(elem).find('.range').css("width",posMax - posMin +'%');
};
return {
template: '<div class="slider horizontal">'+
'<div class="range"></div>'+
'<a class="handle min" ng-mousedown="mouseDownMin($event)"></a>'+
'<a class="handle max" ng-mousedown="mouseDownMax($event)"></a>'+
'</div>',
replace: true,
restrict: 'E',
scope:{
valueMin:"=",
valueMax:"="
},
link: function postLink(scope, element, attrs) {
// Initilization
var dragging = false;
var startPointXMin = 0;
var startPointXMax = 0;
var xPosMin = 0;
var xPosMax = 0;
var settings = {
"min" : (typeof(attrs.min) !== "undefined" ? parseInt(attrs.min,10) : 0),
"max" : (typeof(attrs.max) !== "undefined" ? parseInt(attrs.max,10) : 100),
"step" : (typeof(attrs.step) !== "undefined" ? parseInt(attrs.step,10) : 1)
};
if ( typeof(scope.valueMin) == "undefined" || scope.valueMin === '' )
scope.valueMin = settings.min;
if ( typeof(scope.valueMax) == "undefined" || scope.valueMax === '' )
scope.valueMax = settings.max;
// Track changes only from the outside of the directive
scope.$watch('valueMin', function() {
if (dragging) return;
xPosMin = ( scope.valueMin - settings.min ) / (settings.max - settings.min ) * 100;
if(xPosMin < 0) {
xPosMin = 0;
} else if(xPosMin > 100) {
xPosMin = 100;
}
moveHandle("min",element,xPosMin);
moveRange(element,xPosMin,xPosMax);
});
scope.$watch('valueMax', function() {
if (dragging) return;
xPosMax = ( scope.valueMax - settings.min ) / (settings.max - settings.min ) * 100;
if(xPosMax < 0) {
xPosMax = 0;
} else if(xPosMax > 100) {
xPosMax = 100;
}
moveHandle("max",element,xPosMax);
moveRange(element,xPosMin,xPosMax);
});
// Real action control is here
scope.mouseDownMin = function($event) {
dragging = true;
startPointXMin = $event.pageX;
// Bind to full document, to make move easiery (not to lose focus on y axis)
$document.on('mousemove', function($event) {
if(!dragging) return;
//Calculate handle position
var moveDelta = $event.pageX - startPointXMin;
xPosMin = xPosMin + ( (moveDelta / element.outerWidth()) * 100 );
if(xPosMin < 0) {
xPosMin = 0;
} else if(xPosMin > xPosMax) {
xPosMin = xPosMax;
} else {
// Prevent generating "lag" if moving outside window
startPointXMin = $event.pageX;
}
scope.valueMin = Math.round((((settings.max - settings.min ) * (xPosMin / 100))+settings.min)/settings.step ) * settings.step;
scope.$apply();
// Move the Handle
moveHandle("min", element,xPosMin);
moveRange(element,xPosMin,xPosMax);
});
$document.mouseup(function(){
dragging = false;
$document.unbind('mousemove');
$document.unbind('mousemove');
});
};
scope.mouseDownMax = function($event) {
dragging = true;
startPointXMax = $event.pageX;
// Bind to full document, to make move easiery (not to lose focus on y axis)
$document.on('mousemove', function($event) {
if(!dragging) return;
//Calculate handle position
var moveDelta = $event.pageX - startPointXMax;
xPosMax = xPosMax + ( (moveDelta / element.outerWidth()) * 100 );
if(xPosMax > 100) {
xPosMax = 100;
} else if(xPosMax < xPosMin) {
xPosMax = xPosMin;
} else {
// Prevent generating "lag" if moving outside window
startPointXMax = $event.pageX;
}
scope.valueMax = Math.round((((settings.max - settings.min ) * (xPosMax / 100))+settings.min)/settings.step ) * settings.step;
scope.$apply();
// Move the Handle
moveHandle("max", element,xPosMax);
moveRange(element,xPosMin,xPosMax);
});
$document.mouseup(function(){
dragging = false;
$document.unbind('mousemove');
$document.unbind('mousemove');
});
};
}
};
}]);
app.js:
var myApp = angular.module("filterApp", []);
myApp.controller('ExampleController', ['$scope', '$window', function($scope, $window) {
$scope.greeting = 'Hello, World!';
$scope.doGreeting = function(greeting) {
$window.alert(greeting);
};
}]);
myApp.controller('coolCtrl', function($scope) {
$scope.whoAmI = function(){
console.log("This is whoAmI function in the coolCtrl!");
};
});
myApp.controller('mainCtrl', function($scope, ProductDataService){
$scope.helloWorld = function(){
console.log("This is helloWorld function in the mailCtrl!");
};
$scope.items = ProductDataService.getItems();
$scope.brands = ProductDataService.getBrands();
$scope.refresh = function(){
location.reload();
};
$scope.showPopUpMsg = false;
$scope.openPopUp = function( text ) {
$scope.showPopUpMsg = true;
$scope.popUpMsgContent = text;
$scope.minimun = 123;
};
});
jilters.js:
myApp.filter('brandsfilter', function () {
return function(input, filter) {
var result = [];
angular.forEach(input, function (item) {
angular.forEach(filter, function (isfiltered, brand) {
if (isfiltered && brand === item.brand) {
result.push(item);
}
});
});
return result;
};
});
index.php:
<?php
require 'scripts/mail_script.php';
?>
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<!-- Place favicon.ico in the root directory -->
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/bootstrap.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <!-- for slider work -->
</head>
<body ng-app="filterApp" ng-controller='mainCtrl'>
<!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<!-- Add your site or application content here -->
<div class="container">
<section class='top' >
<h1>Filter</h1>
<!-- //// http://embed.plnkr.co/woqn3i/ /// -->
<!-- ///////// -->
<div class="row" id='items'>
<div>
<div class="col-md-4" ><h2>params:</h2>
<div ng-controller="priceCtrl">
<p>Choose price:</p>
<p>min: <input type="number" ng-model="search.amount_min"/> $</p>
<p>max: <input type="number" ng-model="search.amount_max"/> $</p>
<slider-range min="14000" max="48600" step="100" value-min="search.amount_min" value-max="search.amount_max"></slider-range>
</div>
<hr>
<p>По названию:</p>
<p><input type="text" ng-model="price" /></p>
<p>Brand:</p>
<ul >
<li ng-repeat="(brand, value) in brands">
<input type="checkbox" ng-model="brands[brand]" /> {{brand}}
</li>
</ul>
<hr>
<!-- //// http://embed.plnkr.co/woqn3i/ /// -->
<div ng-controller="filterCtrl">
<p>length:</p>
<p>От: <input type="text" ng-model="search.price_min"/> meters</p>
<p>До: <input type="text" ng-model="search.price_max"/> meters</p>
<slider-range min="2.5" max="12" value-min="search.price_min" value-max="search.price_max"></slider-range>
<hr>
<p>friquincy:</p>
<p>Min: <input type="number" ng-model="search.amount_min"/> times</p>
<p>Max: <input type="number" ng-model="search.amount_max"/> times</p>
<slider-range min="300" max="10000" step="100" value-min="search.amount_min" value-max="search.amount_max"></slider-range>
</div>
<hr>
<!-- ///////// -->
<div class="actions"/>
<input type="button" value="Сбросить" ng-click='refresh()'>
</div>
</div>
<div class="col-md-8"><h2>______ kinds</h2>
<?php
if($success) echo '<h4 class="bg-success text-center">'.'Сообщение отправлено!' . '</h4>';
if($error_message) echo '<h4 class="bg-danger text-center">'.'Сообщение не отправлено:' . $error_message. '</h4>';
?>
<div class="row">
<!-- LOOP.-->
<div ng-repeat="item in items | filter:price | orderBy:price | brandsfilter:brands ">
<div class="col-md-4 col-sm-6 col-sx-12">
<div class="item-inner">
<div class="image-product">
<div class="caption">
<div class="box-view">
<div class="name">{{item.name}}</div>
</div>
</div>
<img src="{{item.pict}}" alt="{{item.name}}" title="{{item.name}}" class="img-responsive">
<p class="price"><span class="price">Price: {{item.price}} $.</span></p>
<p class="description">{{item.name}} - just another piece of information, first preporty is {{item.len}} m. <br>another is: {{item.friq}} per day. </p>
</div>
</div>
</div><!-- col -->
</div> <!-- ng-repeat -->
</div> <!-- row -->
</div>
</div> <!-- mainCtrl -->
</section>
</div>
<div class="panel-footer">
<script src="vendor/angular.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/services.js"></script>
<script src="scripts/filters.js"></script>
<script src="scripts/slider.js"></script>
<script src="scripts/slider_price.js"></script>
<script src="vendor/jquery.js"></script>
<script src="vendor/bootstrap.js"></script>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
</div>
</body>
</html>
AngularJS built-in filter which you already used supports multiple keywords filter see, you only need to implement comparator function to fulfill your needs.
First, change your filter in template to
<div ng-repeat="item in items | filter:myFilters:myComparator | orderBy:price">
then inside your filterCtrl you need to define myFilters and myComparator
$scope.myFilters = {price: 4000, brand: 'abc'};
$scope.myComparator = function(actual, expected) {
if (actual == parseInt(actual)) {
return actual > expected;
}
else {
return actual == expected;
}
}
Inside myComparator you can customise how you want to filter it (exact match, arithmetic comparison or partial match, just remember to return Boolean.
Just update $scope.myFilters whenever your filter keywords changed, the result will be updated in next digest cycle.

Categories