Home > other >  How can I update the x,y and r value in d3.js using a range slider/scroll through arrays? (d3.js)
How can I update the x,y and r value in d3.js using a range slider/scroll through arrays? (d3.js)

Time:01-13

I am trying to plot a bubble chart that also lets you display change in data over time using a range slider. This would require "scrolling" through an array and update the x,y and r values of the bubbles accordingly. I was able to setup the range slider and plot the basic chart but I have no idea how I can update the values with the slider. Everything I found online until now just used the value of the slider as an input for the data.

The data structure i thought would make sense would look like this:

let data = [
{
name: 'Entry1', 
year: [2000, 2001, 2002, 2003, 2004, 2005],
radius: [0, 0, 20, 30, 40, 60], 
xVal: [0, 0, 40, 40, 50, 30], 
yVal: [0, 0, 20, 40, 10, 70]},
{
name: 'Entry2', 
year: [2000, 2001, 2002, 2003, 2004, 2005],
radius: [0, 0, 0, 0, 20, 15], 
xVal: [0, 0, 0, 0, 15, 30], 
yVal: [0, 0, 0, 0, 20, 50]},
{
name: 'Entry3', 
year: [2000, 2001, 2002, 2003, 2004, 2005],
radius: [10, 20, 30, 40, 30, 10], 
xVal: [5, 20, 20, 50, 40, 20], 
yVal: [10, 30, 20, 80, 40, 20]},
];

It would be great if someone could point me in the right direction here :) Thanks guys!

Here is the code I have right now (I removed the arrays to make it work) https://jsfiddle.net/qgesxf1k/11/

CodePudding user response:

I solved the problem myself but wanted to leave the question up if anyone has a similar issue.

//The Data
let data = [
  { name: 'Entry1',radius: [30, 35, 40, 45, 50], xVal: [.20, .25, .30, .35, .40], yVal: [.20, .25, .30, .35, .40]},
  { name: 'Entry2',radius: [10, 15, 20, 25, 30], xVal: [.60, .65, .70, .75, .80], yVal: [.60, .65, .70, .75, .80]},
];

//Plot SVG
const width = 600;
const height = 600;
const margin = { top: 20, right: 20, bottom: 20, left: 20 };
const svg = d3.select('#content').append('svg').attr('viewBox', [0, 0, width, height]).attr('preserveAspectRatio', 'xMidYMid meet');

//Build Axis
const xScale = d3.scaleLinear().domain([0, 1]).range([margin.left, width - margin.right]);
const yScale = d3.scaleLinear().domain([1, 0]).range([margin.top, height - margin.bottom]);
const xAxis = d3.axisBottom(xScale).ticks(1);
const yAxis = d3.axisLeft(yScale).ticks(1);
const xAxisGroup = svg.append('g').attr("transform", "translate(0,"   (height - margin.top)   ")").call(xAxis);
const yAxisGroup = svg.append('g').attr("transform", "translate("  (margin.right)  ",0)").call(yAxis);

//Load the initial Data and set the index of the array to 0
const bubbles = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', d => xScale(d.xVal[0]))
.attr('cy', d => yScale(d.yVal[0]))
.attr('r', d => d.radius[0])

//Update when slider input changes --> HTML oninput="updateData();"
function updateData() {

  //get the slider value
  let i = document.getElementById('timeSlider').value;
  d3.select('svg')
        .selectAll('circle')
    //call the data
        .data(data)
    //slide trough the index of the array and return the corresponding value
    .attr('cx', d => xScale(d.xVal[i]))
    .attr('cy', d => yScale(d.yVal[i]))
    .attr('r', d => d.radius[i])
}
<script src="https://d3js.org/d3.v7.min.js"></script>
<div id="content"></div>
<input id="timeSlider" type="range" value="0" min="0" max="4" oninput="updateData();">

  • Related