Я пытаюсь разными способами создать пузырьковую диаграмму, форсируя левую часть страницы в зависимости от значения. Наибольшее значение пузыря должно быть в верхнем левом углу. Поскольку другие подходы не сработали, я искал пример, в котором пузырьки перемещаются в центр страницы, и теперь я пытаюсь отрегулировать влево, результат, который мне нужен, такой же, как на изображении выше.
Мой код:
function bubbleChart() {
var width = 940;
var height = 600;
var center = {
x: width / 2,
y: height / 2
};
var left = {
x: 0,
y: 300
};
var forceStrength = 0.03;
var svg = null;
var bubbles = null;
var nodes = [];
function charge(d) {
return -Math.pow(d.radius, 2.0) * forceStrength;
}
var simulation = d3.forceSimulation()
.velocityDecay(0.2)
.force('x', d3.forceX().strength(forceStrength).x(left.x))
.force('y', d3.forceY().strength(forceStrength).y(left.y))
.force('charge', d3.forceManyBody().strength(charge))
.on('tick', ticked);
simulation.stop();
var fillColor = d3.scaleOrdinal()
.domain(['low', 'medium', 'high'])
.range(['#d84b2a', '#beccae', '#7aa25c']);
function createNodes(rawData) {
var maxAmount = d3.max(rawData, function(d) {
return +d.total_amount;
});
var radiusScale = d3.scalePow()
.exponent(0.5)
.range([2, 85])
.domain([0, maxAmount]);
var myNodes = rawData.map(function(d) {
return {
id: d.id,
radius: radiusScale(+d.total_amount),
value: +d.total_amount,
name: d.grant_title,
org: d.organization,
group: d.group,
year: d.start_year,
x: Math.random() * 900,
y: Math.random() * 800
};
});
myNodes.sort(function(a, b) {
return b.value - a.value;
});
return myNodes;
}
var chart = function chart(selector, rawData) {
nodes = createNodes(rawData);
svg = d3.select(selector)
.append('svg')
.attr('width', width)
.attr('height', height);
bubbles = svg.selectAll('.bubble')
.data(nodes, function(d) {
return d.id;
});
var bubblesE = bubbles.enter().append('circle')
.classed('bubble', true)
.attr('r', 0)
.attr('fill', function(d) {
return fillColor(d.group);
})
.attr('stroke', function(d) {
return d3.rgb(fillColor(d.group)).darker();
})
.attr('stroke-width', 2)
.on('mouseover', showDetail)
.on('mouseout', hideDetail);
bubbles = bubbles.merge(bubblesE);
bubbles.transition()
.duration(2000)
.attr('r', function(d) {
return d.radius;
});
simulation.nodes(nodes);
groupBubbles();
};
function ticked() {
bubbles
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
});
}
function nodeYearPos(d) {
return yearCenters[d.year].x;
}
function groupBubbles() {
hideYearTitles();
// @v4 Reset the 'x' force to draw the bubbles to the center.
simulation.force('x', d3.forceX().strength(forceStrength).x(center.x));
// @v4 We can reset the alpha value and restart the simulation
simulation.alpha(1).restart();
}
function splitBubbles() {
showYearTitles();
// @v4 Reset the 'x' force to draw the bubbles to their year centers
simulation.force('x', d3.forceX().strength(forceStrength).x(nodeYearPos));
// @v4 We can reset the alpha value and restart the simulation
simulation.alpha(1).restart();
}
function hideYearTitles() {
svg.selectAll('.year').remove();
}
function showYearTitles() {
// Another way to do this would be to create
// the year texts once and then just hide them.
var yearsData = d3.keys(yearsTitleX);
var years = svg.selectAll('.year')
.data(yearsData);
years.enter().append('text')
.attr('class', 'year')
.attr('x', function(d) {
return yearsTitleX[d];
})
.attr('y', 40)
.attr('text-anchor', 'middle')
.text(function(d) {
return d;
});
}
function showDetail(d) {
// change outline to indicate hover state.
d3.select(this).attr('stroke', 'black');
var content = '';
tooltip.showTooltip(content, d3.event);
}
function hideDetail(d) {
// reset outline
d3.select(this)
.attr('stroke', d3.rgb(fillColor(d.group)).darker());
tooltip.hideTooltip();
}
Это мой полный код на Вижубе: https://vizhub.com/barbosa-renan/2864204410d54af5a5c402cdfdd9959d?edit=files&file=index.js
Примечание: в других попытках я пытался использовать .domain () и .range, но в этом сценарии это не сработало, потому что, когда у меня есть пузырьки с очень высоким значением и другие с очень низкое значение, они очень далеки.