Search code examples
jqueryamchartsjquery-ui-slideramcharts4

Using Jquery UI Slider with AMCharts 4 Pie Chart


I can't seem to get the Jquery UI slider to work with an AMCharts 4 pie chart. I'm doing something incorrectly with the slider function, but I'm not 100% sure what's causing the issue.

Ideally, I want to use the slider to cycle through several data sets in an array. This concept works fine with a regular HTML range slider, but I think the Jquery route is a bit more extendable. Has anyone else had success in implementing the Jquery UI slider with an AM Charts 4 pie chart? Any pointers you'd like to share? Greatly appreciate any insight!

  

// Set theme
am4core.useTheme(am4themes_animated);

// Create chart instance
var chart2 = am4core.create("chartdiv2", am4charts.PieChart);

var chart2Data = [
    // 50/40/10
    [
        { category: "U.S. Equities", value: 0.55},
        { category: "U.S. Fixed Income", value: 0.40},
        { category: "Hybrid Strategy", value: 0.07},
        ],
     // 40/40/20
        [
        { category: "U.S. Equities", value: .50},
        { category: "U.S. Fixed Income", value: .40},
        { category: "Hybrid Strategy", value: .14},
        
    ],
   // 30/40/30
    [
        { category: "U.S. Equities", value: .45},
        { category: "U.S. Fixed Income", value: .40},
        { category: "Hybrid Strategy", value: .21},
       
    ],
     // 20/40/40
    [
        { category: "U.S. Equities", value: .40},
        { category: "U.S. Fixed Incomed", value: .40},
        { category: "Hybrid Strategy", value: .28},
       
    ],
    // 10/40/50
    [
        { category: "U.S. Equities", value: .35},
        { category: "U.S. Fixed Income", value: .40},
        { category: "Hybrid Strategy", value: .35},
        
    ]
];

// Add data
chart2.data = chart2Data[0];

// Add and configure Series
var pieSeries = chart2.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "value";
pieSeries.dataFields.category = "category";

// Let's cut a hole in our Pie chart the size of 40% the radius
chart2.innerRadius = am4core.percent(40);

// Put a thick white border around each Slice
pieSeries.slices.template.stroke = am4core.color("#4a2abb");
pieSeries.slices.template.strokeWidth = 2;
pieSeries.slices.template.strokeOpacity = 1;


// Add a legend
chart2.legend = new am4charts.Legend();
chart2.legend.position = "right";

//Binds data to HTML range slider, carryover from AM Charts 3
function selectDataset(d) {
    chart2.data = chart2Data[d];
    chart2.validateData();
    chart2.animateAgain();
}

$( function() {
  $( "#slider" ).slider({
    range: true,
    min: 0,
    max: 4,
    step: 1,
    value: 0,
    "create": function( event, ui ) {
          var dataSet = chart2Data[0];
          $("#slider .ui-slider-handle").text(dataSet.category);
        },
    slide: function( event, ui )  {
          var dataSet = chart2Data[ui.value];
          e.chart2.dataProvider = dataSet.value;
          e.chart2.validateData();
          $(ui.handle).text(dataSet.category);
        }
  });
} );

//Add exposure value to middle of chart
var label = pieSeries.createChild(am4core.Label);
label.text = "${values.value.sum}";
label.horizontalCenter = "middle";
label.verticalCenter = "middle";
label.fontSize = 40;
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv2 {
  width: 100%;
  height: 400px;
}

#slider {
  margin-top: 20px;
}

.ui-slider .ui-slider-handle {
  width: 3.2em!important;
  text-align: center;
  margin-left: -1.6em!important;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>

<div class="container">
<div id="chartdiv2"></div>
<input type="range" min="0" max="4" value="0" name="dataset" step="0" list="ticks" onchange="selectDataset(this.value)">
 
<datalist id="ticks">
  <option>0</option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
</datalist>

 <div id="slider"></div>
</div>


Solution

  • If your question is how to make your current code work with jQuery's Slider, then the issue lies in your slide function option:

    slide: function(event, ui)  {
        var dataSet = chart2Data[ui.value];
    
        // "e" doesn't exist here, and nor would changing it to "event" work
        e.chart2.dataProvider = dataSet.value;
        e.chart2.validateData();
    
        $(ui.handle).text(dataSet.category);
    }
    

    Change to the following:

    slide: function(event, ui)  {
        var dataSet = chart2Data[ui.value];
    
        // same as the selectDataset() function for the regular HTML range slider
        chart2.data = dataSet;
    
        chart2.validateData();
        $(ui.handle).text(dataSet.category);
    }
    

    Working example:

    // Set theme
    am4core.useTheme(am4themes_animated);
    
    // Create chart instance
    var chart2 = am4core.create("chartdiv2", am4charts.PieChart);
    
    var chart2Data = [
      // 50/40/10
      [{
          category: "U.S. Equities",
          value: 0.55
        },
        {
          category: "U.S. Fixed Income",
          value: 0.40
        },
        {
          category: "Hybrid Strategy",
          value: 0.07
        },
      ],
      // 40/40/20
      [{
          category: "U.S. Equities",
          value: .50
        },
        {
          category: "U.S. Fixed Income",
          value: .40
        },
        {
          category: "Hybrid Strategy",
          value: .14
        },
    
      ],
      // 30/40/30
      [{
          category: "U.S. Equities",
          value: .45
        },
        {
          category: "U.S. Fixed Income",
          value: .40
        },
        {
          category: "Hybrid Strategy",
          value: .21
        },
    
      ],
      // 20/40/40
      [{
          category: "U.S. Equities",
          value: .40
        },
        {
          category: "U.S. Fixed Incomed",
          value: .40
        },
        {
          category: "Hybrid Strategy",
          value: .28
        },
    
      ],
      // 10/40/50
      [{
          category: "U.S. Equities",
          value: .35
        },
        {
          category: "U.S. Fixed Income",
          value: .40
        },
        {
          category: "Hybrid Strategy",
          value: .35
        },
    
      ]
    ];
    
    // Add data
    chart2.data = chart2Data[0];
    
    // Add and configure Series
    var pieSeries = chart2.series.push(new am4charts.PieSeries());
    pieSeries.dataFields.value = "value";
    pieSeries.dataFields.category = "category";
    
    // Let's cut a hole in our Pie chart the size of 40% the radius
    chart2.innerRadius = am4core.percent(40);
    
    // Put a thick white border around each Slice
    pieSeries.slices.template.stroke = am4core.color("#4a2abb");
    pieSeries.slices.template.strokeWidth = 2;
    pieSeries.slices.template.strokeOpacity = 1;
    
    
    // Add a legend
    chart2.legend = new am4charts.Legend();
    chart2.legend.position = "right";
    
    $(function() {
      $("#slider").slider({
        range: true,
        min: 0,
        max: 4,
        step: 1,
        value: 0,
        create: function(event, ui) {
          var dataSet = chart2Data[0];
          $("#slider .ui-slider-handle").text(dataSet.category);
        },
        slide: function(event, ui) {
          var dataSet = chart2Data[ui.value];
          chart2.data = dataSet;
          chart2.validateData();
          $(ui.handle).text(dataSet.category);
        }
      });
    });
    
    //Add exposure value to middle of chart
    var label = pieSeries.createChild(am4core.Label);
    label.text = "${values.value.sum}";
    label.horizontalCenter = "middle";
    label.verticalCenter = "middle";
    label.fontSize = 40;
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    }
    
    #chartdiv2 {
      width: 100%;
      height: 400px;
    }
    
    #slider {
      margin-top: 20px;
    }
    
    .ui-slider .ui-slider-handle {
      width: 3.2em!important;
      text-align: center;
      margin-left: -1.6em!important;
    }
    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <script src="https://www.amcharts.com/lib/4/core.js"></script>
    <script src="https://www.amcharts.com/lib/4/charts.js"></script>
    <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
    
    <div class="container">
      <div id="chartdiv2"></div>
    
      <datalist id="ticks">
      <option>0</option>
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
    </datalist>
    
      <div id="slider"></div>
    </div>