function frontierByHull(data, maxWTP) {
const points = data.map((d, i) => [d.cost, d.benefit, d.index]);
const initial_hull = d3.polygonHull(points);
let hull = initial_hull.map((d, i) => {
return _.assign({
cost: d[0],
benefit: d[1],
original_index: d[2],
hull_index: i,
on_frontier: false
});
});
const min_cost_index = _.minBy(hull, 'cost').hull_index;
hull = hull.slice(min_cost_index).concat(hull.slice(0, min_cost_index));
let previous_benefit = -Infinity;
let previous_cost = 0;
hull.forEach(d => {
let wtp = (d.cost - previous_cost) / (d.benefit - previous_benefit);
if (d.benefit >= previous_benefit && wtp <= maxWTP) {
d.on_frontier = true;
previous_cost = d.cost;
previous_benefit = d.benefit;
}
});
return hull.filter(d => d.on_frontier).map(d => d.original_index);
}