mdewilde / chart

Java library for use with Chart.js javascript library
Apache License 2.0
112 stars 43 forks source link

Animation onComplete callback #26

Open marioconforti opened 5 years ago

marioconforti commented 5 years ago

I'm trying to use an animation onComplete js function, in this way:

Animation<?> animation = new Animation<>();
        JavaScriptFunction js = new JavaScriptFunction("function(){alert(chart.toBase64Image())}");
        animation.setOnComplete(js);
        options.setAnimation(animation);

this is rendered in this way inside options

"animation" : {
      "onComplete" : function(){console.log(chart.toBase64Image())}
    },

but the graph is not rendered at all, and i have no logs to see what's going on. If i put off the option, the graph is rendered correctly.

marioconforti commented 5 years ago

the problem should be that

"animation" : {
      "onComplete" : function(){console.log(chart.toBase64Image())}
    }

is not valid JSON and adding "" will not call the javascript function

Charts.js is expecting valid json when you use it? Because if i pass it as a string.

{
  "type" : "line",
  "data" : {
    "datasets" : [ {
      "data" : [ {
        "t" : 1551273300000,
        "y" : 20.75
      }, {
        "t" : 1551273600000,
        "y" : 20.75
      }, {
        "t" : 1551273900000,
        "y" : 20.75
      }, {
        "t" : 1551274200000,
        "y" : 20.75
      }, {
        "t" : 1551274500000,
        "y" : 20.75
      }, {
        "t" : 1551274800000,
        "y" : 20.75
      }, {
        "t" : 1551275100000,
        "y" : 20.75
      }, {
        "t" : 1551275400000,
        "y" : 20.75
      },  {
        "t" : 1551277800000,
        "y" : 28.0625
      } ],
      "label" : "Label",
      "fill" : false,
      "backgroundColor" : "rgba(0,128,0,1.000)",
      "borderWidth" : 2,
      "borderColor" : "rgba(0,128,0,1.000)"
    } ]
  },
  "options" : {
    "responsive" : true,
    "maintainAspectRatio" : true,
    "title" : {
      "display" : true,
      "position" : "top",
      "text" : "aaaaa"
    },
    "legend" : {
      "position" : "bottom"
    },
    "hover" : {
      "mode" : "dataset"
    },
    "animation" : {
      "onComplete" : function(animation){alert("ok")}
    },
    "scales" : {
      "xAxes" : [ {
        "type" : "time",
        "time" : {
          "displayFormats" : {
            "millisecond" : null,
            "second" : null,
            "minute" : "HH:mm",
            "hour" : "DD/MM HH:mm",
            "day" : "DD/MM HH:mm",
            "week" : null,
            "month" : "DD/MM HH",
            "quarter" : null,
            "year" : null
          },
          "tooltipFormat" : "DD/MM/YY HH:mm"
        }
      } ]
    },
    "elements" : {
      "point" : {
        "radius" : 1,
        "hitRadius" : 2,
        "hoverRadius" : 2
      }
    }
  }
}

i got an error in JS -> Cannot create property 'data' on string

dan-whitehouse commented 3 years ago

Yeah, I just recently downloaded the library and ran into the same issue, just a different callback. My workaround was to exclude the callbacks from the ChartOptions and just include it in my javascript.

Java

    DoughnutDataset respondedYes = new DoughnutDataset()
        .setLabel("Responded Yes")
        .setData(65, 59, 80, 81, 56, 55, 40)
        .addBackgroundColors(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.ORANGE, Color.GRAY, Color.BLACK)
        .setBorderWidth(2)
    ;

    DoughnutDataset respondedNo= new DoughnutDataset()
        .setLabel("Responded No")
        .setData(10, 15, 42, 33, 21, 45, 65)
        .addBackgroundColors(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.ORANGE, Color.GRAY, Color.BLACK)
        .setBorderWidth(2)
    ;

    DoughnutData data = new DoughnutData()
        .addLabels("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
        .addDataset(respondedYes)
        .addDataset(respondedNo)
    ;

    DoughnutOptions options = new DoughnutOptions()
        .setResponsive(true)
        .setRotation(BigDecimal.valueOf(1 * Math.PI))
        .setCircumference(BigDecimal.valueOf(1 * Math.PI))
        .setCutoutPercentage(BigDecimal.valueOf(50.0))
        .setLegend(new Legend()
            .setPosition(Legend.Position.BOTTOM)
        )
        .setAnimation(new DoughnutAnimation()
            .setAnimateScale(true)
            .setAnimateRotate(true)
        )
        .setTooltips(new Tooltips()
            .setEnabled(true)
            .setMode("index")
        )
    ;

    return new DoughnutChart(data, options).toJson();

Javascript

<script>
    const submissionsTodayByRole = (function() {
    const $chart = $('#chart-submissions-today');

    let $fetch = function () {
      $.ajax({
        url: '/v3/api/dashboard/submissionsTodayByRole',
        method: 'GET',
        dataType: "json",
        contentType: "application/json",
        success: function ($json) {
          init($chart, $json);
        }
      });
    }();

    // Methods
    function init($this, $json) {
      const chart = new Chart($this, $json);

      chart.options.tooltips.callbacks.title = function(tooltipItem, data) {
        return data.labels[tooltipItem[0].index];
      }

      chart.options.tooltips.callbacks.label = function(tooltipItem, data) {
        let dataset = data.datasets[tooltipItem.datasetIndex];
        let currentValue = dataset.data[tooltipItem.index];
        return '\\t' + dataset.label + ": " + currentValue;
      }

      // Save to jQuery object
      $this.data('chart', chart);
    }

  })();
</script>