locked
D3.js chart library onchange event not firing RRS feed

  • Question

  • User-94285869 posted


    Hi,

    I'm using D3.js chart library and another library, donut3d.js), (https://gist.github.com/NPashaP/9994181) to create a pie chart which gets its data from SQL Server database.

    In partial view1, _Leaflet.cshtml, I have a select Html control:
    <select id="hucDdl" name="hucDdl"></select>

    In partial view2, _BaseLanduse.cshtml, I created an event listener, inside a document.ready script, for selection change in the combo box, hucDdl:
    <input type="hidden" id="output" name="output"/>
    <script>
    $("#hucDdl").change(function(){
       //get huc value
       var huc;
      if($("#hucDdl").valu() != null)
      {
        huc = $("#hucDdl").val();
      }
      //Call function to change chart data
      ChangeData();
    });

    function ChangeData()
    {
      var huc = $("#hucDdl").val();
      $("#output").html(huc);
      var arr = [];

      $.ajax({
        url: "/Home/GetBaseLulcJson/",
        type:  "GET",
        data: {huccode: huc},
        dataType:  "json",
        contentType:  "application/json; charset=utf-8",
        success: function (result){
          arr = result;
        },
        error: function (data){
        }
    });

    var lulcData = [
        {"label": "Cropland", "value": arr[0], "color": "#ffb3ba"},
        {"label": "Forest", "value": arr[1], "color": "#ffdfba"},
        {"label": "Pasture", "value": arr[2], "color": "#ffffba"},
        {"label": "Rangeland", "value": arr[3], "color": "#baffc9"},
        {"label": "Urban", "value": arr[4], "color": "#bae1ff"}
    ];

    //Draw the chart using donut3d.js -pie is 3d pie chart not donut
    //as indicated by 0 internal radius in last parameter.
    Donut3D.draw("blulcpie", getData(), 90, 50, 90, 40, 30, 0);

    function getData() {
        return lulcData.map(function (d) {
            return { label: d.label, value: +d.value, color: d.color }
        });
    }

    }

    The ChangeData function is not firing, although it works when I'm in Debug mode. What I'm trying to achieve is that when a user selects from the combo box (hucDdl), an ajax call fetches the data from SQL Server, loads it into an array (arr), puts the array into lulcData variable that Donut3D.js script then reads to render the pie chart.   Somehow, the chart is not being rendered.

    Has anyone else used Donut3D.js library?  Can anyone point out where I'm going wrong?  Appeciate any help.

    Monday, August 1, 2016 2:10 PM

Answers

  • User-94285869 posted

    Hi,

    Solved this issue.  I revised my codes as follows:

    Index.cshmtl (main view):

    <!--d3.js references-->
    <script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script>
    <script src="~/myscripts/donut3d.js" type="text/javascript"></script>

    <div id="bLulc">
      <label>Major Landuse</label>
      @Html.Partial("~/Views/Shared/_BaseLanduse.cshtml")
    </div>

    Partial View1 (holds the select HTML control) _Leaflet.cshtml:
    <select id = "hucDdl"></select>

    Partial View2 (contains the 3d pie chart) "_BaseLanduse.cshtml":
    <script type="text/javascript">
        $(document).ready(function () {

            //Set default array values for initial display on page load
            var def_arr = [0.2, 80.3, 1.9, 16.9, 0.7];

           var defData = [
                        { "label": "Cropland", "value": def_arr[0], "color": "#ffb3ba" },
                        { "label": "Forest", "value": def_arr[1], "color": "#ffdfba" },
                        { "label": "Pasture", "value": def_arr[2], "color": "#ffffba" },
                        { "label": "Rangeland", "value": def_arr[3], "color": "#baffc9" },
                        { "label": "Urban", "value": def_arr[4], "color": "#bae1ff" }
            ];

            //Define chart parameters
            var margin = { top: 0, right: 20, bottom: 0, left: 20 }
            var width = 180,
                height = 230 - margin.bottom;

            var svg = d3.select("#bLulc")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

            svg.append("g")
                .data([defData])
                .attr("id", "blulcpie");

            //Draw the chart
            Donut3D.draw("blulcpie", defData, 90, 50, 90, 40, 30, 0);

            //Define legend square size
            var legendSpace = 4;
            var rectSize = 8;

            //Add legend
            defData.forEach(function (d, i) {
                svg.append("rect")
                    .attr("transform", "translate(0," + i * (rectSize + legendSpace) + ")")
                    .attr("class", "rect")
                    .attr("width", rectSize)
                    .attr("height", rectSize)
                    .attr("x", 50)       //x-axis of rect
                    .attr("y", 130)     //y-axis of rect
                    .style("stroke", "#000000")
                    .style("stroke-width", .25)
                    .style("fill", defData[i].color);
                svg.append("text")
                    .attr("class", "legend")
                    .attr("x", rectSize + legendSpace)
                    .attr("y", (i * legendSpace) + (i * rectSize))
                    .attr("dx", 50)      //x-axis of text
                    .attr("dy", 138)    //y-axis of text
                    .style("font-size", "10px")
                    .text(defData[i].label);
            });

           //Event listener when huccode changes
            $("#hucDdl").bind("mousedown mouseup", function () {
                debugger;
                //Get data from SQL Server via Controller
                $.ajax({
                    url: "/Home/GetBaseLulcJson/",
                    type: "GET",
                    data: { huccode: $("#hucDdl").val() },
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    success: function (result) {
                        arr = result;
                        //alert(arr);
                    },
                    error: function (data) {
                        //alert(data);
                    }
                })

               var currData = [
                        { label: "Cropland", value: arr[0], color: "#ffb3ba" },
                        { label: "Forest", value: arr[1], color: "#ffdfba" },
                        { label: "Pasture", value: arr[2], color: "#ffffba" },
                        { label: "Rangeland", value: arr[3], color: "#baffc9" },
                        { label: "Urban", value: arr[4], color: "#bae1ff" }
               ];
                   
               Donut3D.transition("blulcpie", currData, 90, 40, 30, 0);
            });
        });

    In Controller:
            [HttpGet]
            public JsonResult GetBaseLulcJson(string huccode)
            {     
                //Returns single row, selected columns
                var lulcBase = (from f in db.FractionsLulcs
                                where f.HUCCODE == huccode
                                select new
                                {
                                    f.Cropland,
                                    f.Forest,
                                    f.Pasture,
                                    f.Range,
                                    f.Urban
                                }).SingleOrDefault();

                //Convert to percentage
                double?[] lulc = new double?[5];
                lulc[0] = Math.Round(Convert.ToDouble(lulcBase.Cropland)  * 100, 1);
                lulc[1] = Math.Round(Convert.ToDouble(lulcBase.Forest) * 100, 1);
                lulc[2] = Math.Round(Convert.ToDouble(lulcBase.Pasture) * 100, 1);
                lulc[3] = Math.Round(Convert.ToDouble(lulcBase.Range) * 100, 1);
                lulc[4] = Math.Round(Convert.ToDouble(lulcBase.Urban) * 100, 1);

                return Json(lulc, JsonRequestBehavior.AllowGet);
            }

    This is working well now.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 4, 2016 2:00 PM

All replies

  • User-271186128 posted

    Hi mgambone,

    The ChangeData function is not firing, although it works when I'm in Debug mode. What I'm trying to achieve is that when a user selects from the combo box (hucDdl), an ajax call fetches the data from SQL Server, loads it into an array (arr), puts the array into lulcData variable that Donut3D.js script then reads to render the pie chart.   Somehow, the chart is not being rendered.

    Has anyone else used Donut3D.js library?  Can anyone point out where I'm going wrong? 

    As for this issue, I suggest you could use alert() method to show the Ajax call result (success or error message), and you could also use alert() method to check the array value.

    Besides, I suggest you could refer to the following sample, it works well on my side:

            <div>
                <button onclick="changeData()">Change Data</button>
                <script src="http://d3js.org/d3.v3.min.js"></script>
               <%-- <script src="Donut3D.js"></script>--%>
                <script src="Scripts/Donut3D.js"></script>
                <script>
    
                    var salesData = [
                        { label: "Basic", value: 30 , color: "#3366CC" },
                        { label: "Plus", value:10, color: "#DC3912" },
                        { label: "Lite", value:20, color: "#FF9900" },
                        { label: "Elite", value:15, color: "#109618" },
                        { label: "Delux", value:25, color: "#990099" }
                    ];
    
                    var svg = d3.select("body").append("svg").attr("width", 700).attr("height", 300);
    
                    svg.append("g").attr("id", "salesDonut");
    
                    Donut3D.draw("salesDonut", randomData(), 150, 150, 130, 100, 30, 0.4);
    
                    function randomData() {
                        return salesData.map(function (d) {
                            return { label: d.label, value: d.value, color: d.color };
                        });
                    }
                </script>
    
            </div>

    Best regards,
    Dillion

    Tuesday, August 2, 2016 2:50 AM
  • User-94285869 posted

    Hi,

    I tried your suggestion.  I used alert() methods to check my array value.  It's successful--no error message. 

    I think it's not the chart library but the jquery-1.10.2.js that I'm using for my main jquery library.  After the ChangeData runs, I get a return value = undefined from the main jquery script, although the chart itself has already rendered (in debug mode).

    Not sure how to track this error or why it's even called after the chart is drawn (in debug mode).  Will work on this more.

    Thanks for the reply.

    Tuesday, August 2, 2016 10:15 AM
  • User-94285869 posted

    Hi,

    Solved this issue.  I revised my codes as follows:

    Index.cshmtl (main view):

    <!--d3.js references-->
    <script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script>
    <script src="~/myscripts/donut3d.js" type="text/javascript"></script>

    <div id="bLulc">
      <label>Major Landuse</label>
      @Html.Partial("~/Views/Shared/_BaseLanduse.cshtml")
    </div>

    Partial View1 (holds the select HTML control) _Leaflet.cshtml:
    <select id = "hucDdl"></select>

    Partial View2 (contains the 3d pie chart) "_BaseLanduse.cshtml":
    <script type="text/javascript">
        $(document).ready(function () {

            //Set default array values for initial display on page load
            var def_arr = [0.2, 80.3, 1.9, 16.9, 0.7];

           var defData = [
                        { "label": "Cropland", "value": def_arr[0], "color": "#ffb3ba" },
                        { "label": "Forest", "value": def_arr[1], "color": "#ffdfba" },
                        { "label": "Pasture", "value": def_arr[2], "color": "#ffffba" },
                        { "label": "Rangeland", "value": def_arr[3], "color": "#baffc9" },
                        { "label": "Urban", "value": def_arr[4], "color": "#bae1ff" }
            ];

            //Define chart parameters
            var margin = { top: 0, right: 20, bottom: 0, left: 20 }
            var width = 180,
                height = 230 - margin.bottom;

            var svg = d3.select("#bLulc")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

            svg.append("g")
                .data([defData])
                .attr("id", "blulcpie");

            //Draw the chart
            Donut3D.draw("blulcpie", defData, 90, 50, 90, 40, 30, 0);

            //Define legend square size
            var legendSpace = 4;
            var rectSize = 8;

            //Add legend
            defData.forEach(function (d, i) {
                svg.append("rect")
                    .attr("transform", "translate(0," + i * (rectSize + legendSpace) + ")")
                    .attr("class", "rect")
                    .attr("width", rectSize)
                    .attr("height", rectSize)
                    .attr("x", 50)       //x-axis of rect
                    .attr("y", 130)     //y-axis of rect
                    .style("stroke", "#000000")
                    .style("stroke-width", .25)
                    .style("fill", defData[i].color);
                svg.append("text")
                    .attr("class", "legend")
                    .attr("x", rectSize + legendSpace)
                    .attr("y", (i * legendSpace) + (i * rectSize))
                    .attr("dx", 50)      //x-axis of text
                    .attr("dy", 138)    //y-axis of text
                    .style("font-size", "10px")
                    .text(defData[i].label);
            });

           //Event listener when huccode changes
            $("#hucDdl").bind("mousedown mouseup", function () {
                debugger;
                //Get data from SQL Server via Controller
                $.ajax({
                    url: "/Home/GetBaseLulcJson/",
                    type: "GET",
                    data: { huccode: $("#hucDdl").val() },
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    success: function (result) {
                        arr = result;
                        //alert(arr);
                    },
                    error: function (data) {
                        //alert(data);
                    }
                })

               var currData = [
                        { label: "Cropland", value: arr[0], color: "#ffb3ba" },
                        { label: "Forest", value: arr[1], color: "#ffdfba" },
                        { label: "Pasture", value: arr[2], color: "#ffffba" },
                        { label: "Rangeland", value: arr[3], color: "#baffc9" },
                        { label: "Urban", value: arr[4], color: "#bae1ff" }
               ];
                   
               Donut3D.transition("blulcpie", currData, 90, 40, 30, 0);
            });
        });

    In Controller:
            [HttpGet]
            public JsonResult GetBaseLulcJson(string huccode)
            {     
                //Returns single row, selected columns
                var lulcBase = (from f in db.FractionsLulcs
                                where f.HUCCODE == huccode
                                select new
                                {
                                    f.Cropland,
                                    f.Forest,
                                    f.Pasture,
                                    f.Range,
                                    f.Urban
                                }).SingleOrDefault();

                //Convert to percentage
                double?[] lulc = new double?[5];
                lulc[0] = Math.Round(Convert.ToDouble(lulcBase.Cropland)  * 100, 1);
                lulc[1] = Math.Round(Convert.ToDouble(lulcBase.Forest) * 100, 1);
                lulc[2] = Math.Round(Convert.ToDouble(lulcBase.Pasture) * 100, 1);
                lulc[3] = Math.Round(Convert.ToDouble(lulcBase.Range) * 100, 1);
                lulc[4] = Math.Round(Convert.ToDouble(lulcBase.Urban) * 100, 1);

                return Json(lulc, JsonRequestBehavior.AllowGet);
            }

    This is working well now.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 4, 2016 2:00 PM