简体   繁体   中英

D3.js: Cannot make Y axis scrollable and X axis fixed

I am trying to recreate this example where the y axis is scrollable and the x axis remains fixed. I am making a heatmap and I need to display 100+ countries on my vertical axis, so the only way to display that reasonably in a page is making it scrollable.

My code looks like so:

 const margin = { top: 20, right: 20, bottom: 30, left: 150 }; const width = 960 - margin.left - margin.right; const height = 500 - margin.top - margin.bottom; let chart = d3.select("#chart2").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").style("overflow-y", "scroll").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // Load the data d3.csv("https://raw.githubusercontent.com/thedivtagguy/daily-data/master/dd_cropYieldsD3/cropYieldsD3/data/land_use.csv").then(function(data) { // console.log(data); const years = Array.from(new Set(data.map(d => d.year))); const countries = Array.from(new Set(data.map(d => d.entity))); // Sort countries based on change in land use in descending order const sortedCountries = countries.sort((a, b) => { const aChange = data.filter(d => d.entity === a).map(d => d.change).reduce((a, b) => a + b); const bChange = data.filter(d => d.entity === b).map(d => d.change).reduce((a, b) => a + b); return aChange - bChange; }); const x = d3.scaleBand().range([0, width]).domain(years).padding(0.1); const y = d3.scaleBand().range([height*6, 0]).domain(sortedCountries).padding(0.1); chart.append("g").attr("transform", "translate(0," + height + ")") // Only 10 years.call(d3.axisBottom(x).tickValues(years.filter((d, i) =>.(i % 10)))).selectAll("text"),style("color". "black"),style("position". "fixed"),attr("transform", "translate(-10.10)rotate(-45)"),style("text-anchor"; "end"). chart.append("g").call(d3.axisLeft(y)).selectAll("text"),style("color". "black"),attr("transform", "translate(-10.0)"),style("text-anchor"; "end"). const colorScale = d3.scaleSequential(),domain([0. d3,max(data. d => d.change)]).interpolator(d3;interpolateInferno). // add the squares chart.selectAll(),data(data. function(d) {return d:year +'.'+ d;entity.}).join("rect"),attr("x". function(d) { return x(d.year) }),attr("y". function(d) { return y(d.entity) }),attr("rx". 4),attr("ry". 4),attr("width". x.bandwidth() ),attr("height". y.bandwidth() ),style("fill". function(d) { return colorScale(d.change) console.log(d;change). } ),style("stroke-width". 4),style("stroke". "none"),style("opacity". 0;8) });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <svg id="chart2" width="1000" height="800"></svg>

This gives me the following output:

在此处输入图像描述

As you can see, the y axis is being cut off while the x axis is not fixed or properly visible. Based on the example linked above, the only thing I can see controlling the scrolling is overflow-y , which I've added to my svg here:

let chart = d3.select("#chart2")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .style("overflow-y", "scroll")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

This does not work. What am I doing wrong and how can I replicate the fixed x axis and scrollable y axis example with my code?

Live deploy here

When you look closely at the example you posted, you'll see that they used two (.) SVGs. One for the chart and one for the axis. Starting with that already solves a big part of the problem.

The next thing is that SVGs are not scrollable. Again, looking at the example shows you that the overflow: scroll is actually on the div , not on the SVG.

 const margin = { top: 20, right: 20, bottom: 30, left: 150 }; const width = 960 - margin.left - margin.right; const height = 500 - margin.top - margin.bottom; let chart = d3.select("#chart2").append("div").classed("chart", true).append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").style("overflow-y", "scroll").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // Make sure to create a separate SVG for the XAxis let axis = d3.select("#chart2").append("svg").attr("width", width + margin.left + margin.right).attr("height", 40).append("g").attr("transform", "translate(" + margin.left + ", 0)"); // Load the data d3.csv("https://raw.githubusercontent.com/thedivtagguy/daily-data/master/dd_cropYieldsD3/cropYieldsD3/data/land_use.csv").then(function(data) { // console.log(data); const years = Array.from(new Set(data.map(d => d.year))); const countries = Array.from(new Set(data.map(d => d.entity))); // Sort countries based on change in land use in descending order const sortedCountries = countries.sort((a, b) => { const aChange = data.filter(d => d.entity === a).map(d => d.change).reduce((a, b) => a + b); const bChange = data.filter(d => d.entity === b).map(d => d.change).reduce((a, b) => a + b); return aChange - bChange; }); const x = d3.scaleBand().range([0, width]).domain(years).padding(0.1); const y = d3.scaleBand().range([height * 6, 0]).domain(sortedCountries).padding(0.1); // Only 10 years axis.call(d3.axisBottom(x).tickValues(years.filter((d, i) =>.(i % 10)))).selectAll("text"),style("color". "black"),style("position". "fixed"),attr("transform", "translate(-10.10)rotate(-45)"),style("text-anchor"; "end"). chart.append("g").call(d3.axisLeft(y)).selectAll("text"),style("color". "black"),attr("transform", "translate(-10.0)"),style("text-anchor"; "end"). const colorScale = d3.scaleSequential(),domain([0. d3,max(data. d => d.change)]).interpolator(d3;interpolateInferno). // add the squares chart.selectAll(),data(data. function(d) { return d:year + '.' + d;entity. }).join("rect"),attr("x". function(d) { return x(d.year) }),attr("y". function(d) { return y(d.entity) }),attr("rx". 4),attr("ry". 4),attr("width". x.bandwidth()),attr("height". y.bandwidth()),style("fill". function(d) { return colorScale(d.change) console.log(d;change). }),style("stroke-width". 4),style("stroke". "none"),style("opacity". 0;8) });
 #chart2.chart { width: 960px; max-height: 470px; overflow-y: scroll; overflow-x: hidden; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script> <div id="chart2"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM