Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

updating d3 chart with input from form

Have searched far and wide for help on this but cant seem to find anything quite close enough.

In brief, I am trying to update a graph I have produced using d3.js with data from a form on the same page as the graph. I.e. I display a column chart with 3 columns and would like to be able to adjust the height of the 3rd column through a simple input alongside the chart. As of now I am loading the data through d3's csv method so maybe that is not the best way to operate.

If anyone can help I'd greatly appreciate it! I can post code if you'd like but I figured a general explanation might be achievable.

cheers, Allen

Here's how it looks after I got it working:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            body {
                font: 10px sans-serif;
            }
            .axis path,
            .axis line {
              fill: none;
              stroke: #000;
              shape-rendering: crispEdges;
            }

            .bar {
              fill: steelblue;
            }

            .x.axis path {
              display: none;
            }
        </style>
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <script src="http://d3js.org/d3.v3.min.js"></script>
    </head>
    <body>
        <div id="chart"></div>
        <div>
            <form>
                A: <input class="fields" id="a" type="float"/>
                B: <input class="fields" id="b" type="float"/>
                C: <input class="fields" id="c" type="float"/>
                <input type="submit" />
            </form>
        </div>
        <!--d3 code-->
        <script>
            var data = [10,50,200];
            var margin = {top: 20, right: 20, bottom: 30, left: 40},
                width = 960 - margin.left - margin.right,
                height = 500 - margin.top - margin.bottom;
            var formatPercent = d3.format(".0%");

            var x = d3.scale.ordinal()
                .rangeRoundBands([0, width], .1);

            var y = d3.scale.linear()
                .range([height, 0]);

            var xAxis = d3.svg.axis()
                .scale(x)
                .orient("bottom");

            var yAxis = d3.svg.axis()
                .scale(y)
                .orient("left")

            var svg = d3.select(document.getElementById("chart")).append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
              .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            svg.selectAll(".bar")
                .data(data)
              .enter().append("rect")
                .attr("x", function(d, i) { return i * 200; })
                .attr("width", function(d) {return 100;})
                .attr("y", function(d) { return height - d;})
                .attr("height", function(d) { return d; });
        </script>
        <!--on form submit-->
        <script type="text/javascript">
            $("form").submit(function() {
                var newA = document.getElementById("a").value;
                var newB = document.getElementById("b").value;
                var newC = document.getElementById("c").value;

                svg.selectAll("rect")
                    .data([newA, newB, newC])
                    .attr("y", function(d) { return height - d;})
                    .attr("height", function(d) { return d; });

                return false;
            });
        </script>
    </body>
</html>
like image 654
AllenSH Avatar asked Oct 05 '22 21:10

AllenSH


1 Answers

The basic pattern is that you call a function from the onclick handler of your form that updates the data. So in your case with 3 columns, the first two data points would remain the same and the third one would be updated based on the input value (which you can get from the form using d3 or jquery or something like that).

Loading the initial data through d3.csv shouldn't be a problem as long as you're using d3's selection patterns -- see the circles tutorial for some more background on the general idea. So in your handler you would adjust the height based on the new data, which should be the same code that you've used to create the chart initially.

like image 87
Lars Kotthoff Avatar answered Oct 10 '22 02:10

Lars Kotthoff