我正在开发一个应用,试图通过仪表显示一个人的总净资产。我有用于表格和仪表的代码。表单的输入字段是动态生成的。并且,与“名称”标题相对应的输入字段是一个下拉框,可用于动态填充输入字段中的数据。我尝试了很少的堆栈溢出解决方案来解决我的问题,但是没有一个对我有用。我无法找到根据表格的输出值更新量规的正确方法。
有人可以帮助我吗?我将非常感谢。
这是代码。...
/* code of Gauge */
(function () {
var Needle, arc, arcEndRad, arcStartRad, barWidth, chart, chartInset, degToRad, el, endPadRad, height, i, margin, needle, numSections, padRad, percToDeg, percToRad, percent, radius, ref, sectionIndx, sectionPerc, startPadRad, svg, totalPercent, width;
percent = .65;
barWidth = 60;
numSections = 3;
// / 2 for HALF circle
sectionPerc = [0.1, 0.25, 0.15];
padRad = 0;
chartInset = 10;
// start at 270deg
totalPercent = .75;
el = d3.select('.chart-gauge');
margin = {
top: 20,
right: 20,
bottom: 30,
left: 20 };
width = el[0][0].offsetWidth - margin.left - margin.right;
height = width;
radius = Math.min(width, height) / 2;
percToDeg = function (perc) {
return perc * 360;
};
percToRad = function (perc) {
return degToRad(percToDeg(perc));
};
degToRad = function (deg) {
return deg * Math.PI / 180;
};
svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);
chart = svg.append('g').attr('transform', `translate(${(width + margin.left) / 2}, ${(height + margin.top) / 2})`);
// build gauge bg
for (sectionIndx = i = 1, ref = numSections; 1 <= ref ? i <= ref : i >= ref; sectionIndx = 1 <= ref ? ++i : --i) {
arcStartRad = percToRad(totalPercent);
arcEndRad = arcStartRad + percToRad(sectionPerc[sectionIndx-1]);
totalPercent += sectionPerc[sectionIndx-1];
startPadRad = 0;
endPadRad = 0;
arc = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth).startAngle(arcStartRad + startPadRad).endAngle(arcEndRad - endPadRad);
chart.append('path').attr('class', `arc chart-color${sectionIndx}`).attr('d', arc);
}
Needle = class Needle {
constructor(len, radius1) {
this.len = len;
this.radius = radius1;
}
drawOn(el, perc) {
el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);
return el.append('path').attr('class', 'needle').attr('d', this.mkCmd(perc));
}
animateOn(el, perc) {
var self;
self = this;
return el.transition().delay(500).ease('elastic').duration(3000).selectAll('.needle').tween('progress', function () {
return function (percentOfPercent) {
var progress;
progress = percentOfPercent * perc;
return d3.select(this).attr('d', self.mkCmd(progress));
};
});
}
mkCmd(perc) {
var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY;
thetaRad = percToRad(perc / 2); // half circle
centerX = 0;
centerY = 0;
topX = centerX - this.len * Math.cos(thetaRad);
topY = centerY - this.len * Math.sin(thetaRad);
leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI / 2);
leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI / 2);
rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI / 2);
rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI / 2);
return `M ${leftX} ${leftY} L ${topX} ${topY} L ${rightX} ${rightY}`;
}};
needle = new Needle(140, 15);
needle.drawOn(chart, 0);
needle.animateOn(chart, percent);
var percentage = percent*100
if (percentage > 70) {
rating = 'High'
}
else if (percentage > 20 && percentage < 70) {
rating = 'Average'
}
else {
rating = 'Low'
}
percentValue = document.getElementById('percentValue');
percentValue.innerText = rating;
}).call(this);
/* Code of Form */
let headings = []
const defaults = {Stocks: 100, Bonds: 60};
const calcVal = {};
// appending the created HTML string to the DOM
function initInputs(headingList) {
jQuery(".fields").append(createInputsHTML(headingList))
}
// the HTMLT template that is going to be appended
// to the DOM
function createInputsHTML(headingList) {
let html = ''
headingList.forEach(heading => {
if (heading !== 'Name') {
html += `<label for="${heading}">${heading}: </label>`
html += `<input type="number" id="${heading}">`
html += '<br>'
}
})
return html
}
// receiving data
// this data arrives later in the app's lifecycle,
// so it's the best to return a Promise object
// that gets resolved (check JS Promise for more information)
function getJSON() {
return new Promise(resolve => {
jQuery.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/12/data-4.txt", function(data) {
resolve(JSON.parse(data))
});
})
}
// processing raw JSON data
function processRawData(data) {
return new Promise(resolve => {
const nameData = []
// creating data array
// handling multiple sheets
Object.values(data).forEach((sheet, index) => {
sheet.forEach((name, i) => {
nameData.push({ ...name
})
// create headings only once
if (index === 0 && i === 0) {
Object.keys(name).forEach(item => {
headings.push(item.trim())
})
}
})
})
resolve(nameData)
})
}
$(async function() {
let lists = [];
function initAutocomplete(list) {
const thisKey = 'Name'
$("#name").autocomplete('option', 'source', function(request, response) {
response(
list.filter(item => {
if (item[thisKey].toLowerCase().includes(request.term.toLowerCase())) {
item.label = item[thisKey]
return item
}
})
)
})
}
$("#name").autocomplete({
minLength: 3,
source: lists,
focus: function(event, ui) {
// the "species" is constant - it shouldn't be modified
$("#company").val(ui.item.Name);
return false;
},
select: function(event, ui) {
// handling n number of fields / columns
headings.forEach(heading => {
$('#' + heading).val(ui.item[heading])
})
return false;
}
});
// starting data download, processing and usage
getJSON()
.then(json => {
return processRawData(json)
})
.then(data => {
// just so we see what data we are using
// console.log(data)
// make the processed data accessible globally
lists = data
initAutocomplete(lists)
initInputs(headings)
})
});
//calculation for Rating value
$(document).ready(function() {
$("#Cal").click(function() {
var stocksVal = 0,
bondsVal = 0,
landVal = 0;
$(".fields input").each(function() {
var idHeading = $(this).attr("id");
if (idHeading == "Stocks") {
stocksVal = parseInt(calcVal[idHeading]);
stocksVal = !isNaN(stocksVal)? stocksVal : 0;
console.log("calcVal",parseInt(calcVal[idHeading]), idHeading, stocksVal);
}
if (idHeading == "Bonds") {
bondsVal = parseInt(calcVal[idHeading]);
bondsVal = !isNaN(bondsVal)? bondsVal : 0;
}
if (idHeading == "Land") {
landVal = parseInt($(this).val());
landVal = !isNaN(landVal)? landVal : 0;
}
});
var output = (stocksVal) + (bondsVal) + (landVal);
$("output[name='amount']").text(output);
});
});
$('body').on('keyup', 'input', function(){
if($(this).val().indexOf("-") !== -1 || $(this).val() == 0){
if(defaults[$(this).attr('id')]){
calcVal[$(this).attr('id')] = defaults[$(this).attr('id')]
}else{
calcVal[$(this).attr('id')] = parseInt($(this).val());
}
}else{
calcVal[$(this).attr('id')] = $(this).val();
}
})
$(function(){
var $input = $('input:not(:checkbox)'),// Check box is having some value even when not checked so ommitting it.
$register = $('button:button');
$register.attr('disabled', !isFilledForm());
$input.keyup(function() {
$register.prop('disabled', !isFilledForm())
});
function isFilledForm(){
var isFilled = true;
$input.each(function(){
if(!$(this).val()) isFilled = false;
})
return isFilled
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div class="chart-gauge">
<h1 id="percentValue"></h1>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<div class="ui-widget">
<form id="frm1">
<label for="name">Name: </label>
<input id="name"><br /><br />
<div class="fields"></div>
<!-- PLEASE NOTE THAT THE OTHER INPUT FIELDS WILL BE ADDED DYNAMICALLY -->
<button type="button" id="Cal">Button</button>
<p>
<output name="amount" for="calculation">0</output>
</p>
</form>