How to create a slider on a chart in D3.js and show the label of the dynamic value of y?

Here is a simple chart script example.

I am new to learn about D3.js , and I like it, and I am so impressed with it and its creator Mike Bostock.

I created a web page of charts whose values โ€‹โ€‹influence each other, sort of like in Bostok. Rent Versus Buy a calculator in The New York Times .

I tried to create a slider (using JqueryUI) that changes the input value (for example, the $ 250,000 input field shown below), which affects the y value of the chart. It works, but it disappoints in appearance and is not mobile.

I was not able to deal with tutorials or documentation on how to create a slider such as Bostock, here:

XOCLWJE.png

I donโ€™t think Bostok used anything other than D3 to create its own slider and style.

I tried to look at its source code, but I was not lucky enough to find out.

In my sample script , I use the JqueryUI slider ( $("<div class='slider'></div>").insertAfter(input).slider() ) and some CSS.

Are there any D3 features that I haven't found that could help my chart look more like it?

If you could point me in the right direction, how to create (and style) a slider, a y-value label and an axis, I would really appreciate it.

+5
source share
1 answer

Here is a very simple demo that I wrote from scratch, so not based on your code in the fiddle, showing the main aspects of the created dataviz file.

In this demo, I use only D3, no jQuery (mixing D3 with jQuery gives me headaches):

 var width = 500, height = 180, padding = 16; var svg = d3.select("#svg") .append("svg") .attr("width", width) .attr("height", height); var data = d3.range(1, 21); var xScale = d3.scaleBand() .domain(data) .range([padding * 2, width - padding]) .padding(0.2); var yScale = d3.scaleLinear() .domain([0, d3.max(data, d => d)]) .range([height - padding, padding]); var bars = svg.selectAll(".bars") .data(data) .enter() .append("rect") .attr("x", d => xScale(d)) .attr("width", xScale.bandwidth()) .attr("y", d => yScale(d)) .attr("height", d => height - padding - yScale(d)) .attr("fill", (d => d3.select("#slider").node().value == d ? "firebrick" : "teal")); var xAxis = d3.axisBottom(xScale); var yAxis = d3.axisLeft(yScale); var gX = svg.append("g") .attr("transform", "translate(0," + (height - padding) + ")") .call(xAxis); var gY = svg.append("g") .attr("transform", "translate(" + padding * 2 + ",0)") .call(yAxis); d3.select("#slider").on("input", function() { var currentValue = this.value; yScale.domain([0, currentValue * 2]) bars.attr("y", d => yScale(d)) .attr("height", d => height - padding - yScale(d)) .attr("fill", (d => currentValue == d ? "firebrick" : "teal")); gY.call(yAxis); }) 
 #slider { width: 435px; } #sliderdiv{ padding-left: 40px; } 
 <script src="https://d3js.org/d3.v4.min.js"></script> <div id="svg"></div> <div id="sliderdiv"><input id="slider" type="range" min="1" max="20" step="1" value="10"/></div> 

Explanation:

In this example, I use plain HTML input for the slider:

 <input id="slider" type="range" min="1" max="20" step="1" value="10"/> 

Then we get the changes in this slider using this function:

 d3.select("#slider").on("input", function() { var currentValue = this.value; yScale.domain([0, currentValue * 2]) bars.attr("y", d => yScale(d)) .attr("height", d => height - padding - yScale(d)) .attr("fill", (d => currentValue == d ? "firebrick" : "teal")); gY.call(yAxis); }) 

Inside this function, we have 3 main steps. First we get the current value of the slider:

 var currentValue = this.value; 

And using this value, we change the scale of y:

 yScale.domain([0, currentValue * 2]) 

Thus, the selected strip will always remain at the same height, exactly the same as in the Bostok code. Then we update the lines:

 bars.attr("y", d => yScale(d)) .attr("height", d => height - padding - yScale(d)) .attr("fill", (d => currentValue == d ? "firebrick" : "teal")); 

And finally, the y axis:

 gY.call(yAxis); 
+4
source

Source: https://habr.com/ru/post/1264051/


All Articles