|
@@ -91,60 +91,43 @@ export default {
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
onWeightChange(changedCode) {
|
|
onWeightChange(changedCode) {
|
|
|
- // 1. Clamp the changed dimension
|
|
|
|
|
const changed = this.dimensions.find(function(d) { return d.code === changedCode })
|
|
const changed = this.dimensions.find(function(d) { return d.code === changedCode })
|
|
|
if (changed) {
|
|
if (changed) {
|
|
|
changed.currentValue = Math.max(0, Math.min(100, changed.currentValue))
|
|
changed.currentValue = Math.max(0, Math.min(100, changed.currentValue))
|
|
|
}
|
|
}
|
|
|
var remaining = 100 - this.sum
|
|
var remaining = 100 - this.sum
|
|
|
- if (remaining === 0) {
|
|
|
|
|
|
|
+ if (Math.abs(remaining) < 0.01) {
|
|
|
this.emitValue()
|
|
this.emitValue()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
var others = this.dimensions.filter(function(d) { return d.code !== changedCode })
|
|
var others = this.dimensions.filter(function(d) { return d.code !== changedCode })
|
|
|
if (remaining > 0) {
|
|
if (remaining > 0) {
|
|
|
- // 需要把剩余分配到其他维度
|
|
|
|
|
- var otherTotal = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
|
|
|
|
|
- if (otherTotal === 0) {
|
|
|
|
|
- // 所有其他维度为 0,平分剩余
|
|
|
|
|
- var rest = remaining
|
|
|
|
|
- others.forEach(function(d, i) {
|
|
|
|
|
- d.currentValue = (i === others.length - 1) ? rest : Math.floor(remaining / others.length)
|
|
|
|
|
- if (i < others.length - 1) rest = remaining - d.currentValue
|
|
|
|
|
- })
|
|
|
|
|
- } else {
|
|
|
|
|
- var distSum = 0
|
|
|
|
|
- others.forEach(function(d, i) {
|
|
|
|
|
- if (i === others.length - 1) {
|
|
|
|
|
- d.currentValue = Math.max(0, remaining - distSum)
|
|
|
|
|
- } else {
|
|
|
|
|
- var share = Math.max(0, Math.round((d.currentValue / otherTotal) * remaining))
|
|
|
|
|
- d.currentValue = share
|
|
|
|
|
- distSum += share
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ var othersTotal = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
|
|
|
|
|
+ var exactVals = []
|
|
|
|
|
+ for (var i = 0; i < others.length; i++) {
|
|
|
|
|
+ exactVals.push(othersTotal > 0 ? ((others[i].currentValue || 0) / othersTotal) * remaining : remaining / others.length)
|
|
|
|
|
+ }
|
|
|
|
|
+ var distributed = 0
|
|
|
|
|
+ for (var j = 0; j < others.length - 1; j++) {
|
|
|
|
|
+ var rounded = Math.round(exactVals[j])
|
|
|
|
|
+ others[j].currentValue = Math.max(0, rounded)
|
|
|
|
|
+ distributed += rounded
|
|
|
}
|
|
}
|
|
|
|
|
+ others[others.length - 1].currentValue = Math.max(0, Math.round(remaining - distributed))
|
|
|
} else {
|
|
} else {
|
|
|
- // 超过 100,需要从其他维度扣除
|
|
|
|
|
var excess = -remaining
|
|
var excess = -remaining
|
|
|
- var otherTotal2 = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
|
|
|
|
|
- if (otherTotal2 > 0) {
|
|
|
|
|
- var cutSum = 0
|
|
|
|
|
- others.forEach(function(d, i) {
|
|
|
|
|
- if (i === others.length - 1) {
|
|
|
|
|
- d.currentValue = Math.max(0, (d.currentValue || 0) - (excess - cutSum))
|
|
|
|
|
- } else {
|
|
|
|
|
- var cut = Math.min(d.currentValue || 0, Math.round((d.currentValue / otherTotal2) * excess))
|
|
|
|
|
- d.currentValue = Math.max(0, (d.currentValue || 0) - cut)
|
|
|
|
|
- cutSum += cut
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ var othersTotal2 = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
|
|
|
|
|
+ var exactCuts = []
|
|
|
|
|
+ for (var k = 0; k < others.length; k++) {
|
|
|
|
|
+ exactCuts.push(othersTotal2 > 0 ? ((others[k].currentValue || 0) / othersTotal2) * excess : excess / others.length)
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- // 最后修正浮点误差
|
|
|
|
|
- var finalSum = this.dimensions.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
|
|
|
|
|
- if (finalSum !== 100 && others.length > 0) {
|
|
|
|
|
- others[0].currentValue += 100 - finalSum
|
|
|
|
|
|
|
+ var cutSum = 0
|
|
|
|
|
+ for (var m = 0; m < others.length - 1; m++) {
|
|
|
|
|
+ var cutRounded = Math.round(exactCuts[m])
|
|
|
|
|
+ others[m].currentValue = Math.max(0, (others[m].currentValue || 0) - cutRounded)
|
|
|
|
|
+ cutSum += cutRounded
|
|
|
|
|
+ }
|
|
|
|
|
+ others[others.length - 1].currentValue = Math.max(0, (others[others.length - 1].currentValue || 0) - Math.round(excess - cutSum))
|
|
|
}
|
|
}
|
|
|
this.emitValue()
|
|
this.emitValue()
|
|
|
},
|
|
},
|