Morgan Hautman
Morgan Hautman

Reputation: 3

Changing bonsai code dynamically

I have this part of code

<script>
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'getNewUsers.php',false);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    xhr.send();
    var json;
    if (xhr.readyState == 4 && xhr.status == 200) { // If file is loaded correctly.
        json = JSON.parse(xhr.responseText);
        alert(json.en);

    }
    else if(xhr.readyState == 4 && xhr.status != 200) { // En cas d'erreur !
        alert( ' Une erreur est survenue !\n\nCode :' + xhr.status + '\nTexte : ' + xhr.statusText);
    }
</script>
<script id="bs">
function Sector(x, y, radius, startAngle, endAngle) {
  SpecialAttrPath.call(this, {
    radius: 0,
    startAngle: startAngle,
    endAngle: endAngle
  });
  this.attr({
    x: x,
    y: y,
    radius: radius,
    startAngle: startAngle,
    endAngle: endAngle
  });
}

Sector.prototype = Object.create(SpecialAttrPath.prototype);
Sector.prototype._make = function() {

  var attr = this._attributes,
      radius = attr.radius,
      startAngle = attr.startAngle,
      endAngle = attr.endAngle;

  var startX, startY, endX, endY;
  var diffAngle = Math.abs(endAngle - startAngle);

  this.startX = startX = radius * Math.cos(startAngle);
  this.startY = startY = radius * Math.sin(startAngle);
  if (diffAngle < Math.PI*2) {
    endX = radius * Math.cos(endAngle);
    endY = radius * Math.sin(endAngle);
  } else { // angles differ by more than 2*PI: draw a full circle
    endX = startX;
    endY = startY - .0001;
  }

  this.endX = endX;
  this.endY = endY;

  this.radiusExtentX = radius * Math.cos(startAngle + (endAngle - startAngle)/2);
  this.radiusExtentY = radius * Math.sin(startAngle + (endAngle - startAngle)/2);

  return this.moveTo(0, 0)
    .lineTo(startX, startY)
    .arcTo(radius, radius, 0, (diffAngle < Math.PI) ? 0 : 1, 1, endX, endY)
    .lineTo(0, 0);

};

Sector.prototype.getDimensions = function() {
  var x = this.attr('x'),
      y = this.attr('y'),
      left = Math.min(x, x + this.startX, x + this.endX, x + this.radiusExtentX),
      top = Math.min(y, y + this.startY, y + this.endY, y + this.radiusExtentY),
      right = Math.max(x, x + this.startX, x + this.endX, x + this.radiusExtentX),
      bottom = Math.max(y, y + this.startY, y + this.endY, y + this.radiusExtentY);
  console.log(y, y + this.startY, y + this.endY, y + this.radiusExtentY)
  return {
    left: left,
    top: top,
    width: right - left,
    height: bottom - top
  };
};


PieChart.BASE_COLOR = color('red');

function PieChart(data) {
  this.angle = 0;
  this.labelY = 30;
  this.kolor = PieChart.BASE_COLOR.clone();
  var n = 0;
  for (var i in data) {
    this.slice(i, data[i], n++);
  }
}

PieChart.prototype = {
  slice: function(name, value, i) {

    var start = this.angle,
        end = start + (Math.PI*2) * value/100,
        // Increase hue by .1 with each slice (max of 10 will work)
        kolor = this.kolor = this.kolor.clone().hue(this.kolor.hue()+.1);

    var s = new Sector(
      400, 200, 150,
      start,
      end
    );

    var animDelay = (i * 200) + 'ms';

    var label = this.label(name, value, kolor);

    label.attr({ opacity: 0 });

    s.stroke('#FFF', 3);
    s.fill(kolor);

    s.attr({
      endAngle: start,
      radius: 0
    }).addTo(stage).on('mouseover', over).on('mouseout', out);
    label.on('mouseover', over).on('mouseout', out);

    function over() {
      label.text.attr('fontWeight', 'bold');
      label.animate('.2s', {
        x: 40
      });
      s.animate('.2s', {
        radius: 170,
        fillColor: kolor.lighter(.1)
      }, {
        easing: 'sineOut'
      });
    }

    function out() {
      label.text.attr('fontWeight', '');
      label.animate('.2s', {
        x: 30
      });
      s.animate('.2s', {
        radius: 150,
        fillColor: kolor
      });
    }

    s.animate('.4s', {
      radius: 150,
      startAngle: start,
      endAngle: end
    }, {
      easing: 'sineOut',
      delay: animDelay
    });

    label.animate('.4s', {
      opacity: 1
    }, { delay: animDelay });

    this.angle = end;
  },

  label: function(name, v, fill) {

    var g = new Group().attr({
      x: 30,
      y: this.labelY,
      cursor: 'pointer'
    });

    var t = new Text(name + ' (' + v + '%)').addTo(g);
    var r = new Rect(0, 0, 20, 20, 5).fill(fill).addTo(g);

    t.attr({
      x: 30,
      y: 17,
      textFillColor: 'black',
      fontFamily: 'Arial',
      fontSize: '14'
    });

    g.addTo(stage);
    this.labelY += 30;

    g.text = t;

    return g;
  }
};

new PieChart({
  English: json.en,
  French: 20,
  German: 30,
  Dutch: 5,
  Spanish: 19,
  Others: 18
})


</script>

The problem is I would like to change the pie dynamically using Json, in the demi it is shown with integers but here it is also an integer. This is the line that cause the problem for rendering the pie.

new PieChart({
      English: json.en,

Upvotes: 0

Views: 514

Answers (1)

klipstein
klipstein

Reputation: 111

BonsaiJS is executed in a separate execution environment (mostly worker) and because of that it can't reach objects that were defined outside (in your case the json variable) of the BonsaiJS movie code (in your example <script id="bs">).

You can read about the special execution of BonsaiJS here: http://docs.bonsaijs.org/overview/Execution.html. If you want to pass data from your page to the Bonsai movie execution you can do the following:

  1. Dynamically communicate through sendMessage with the execution context (described here: http://docs.bonsaijs.org/overview/Communication.html)
  2. If you just have to pass data into your context once you can do that through bonsai.run(myNode, {myJson: json}); and access it from within your movie code through stage.options.myJson (documented on the bottom of http://docs.bonsaijs.org/overview/Execution.html).

You also have the third option to move the XMLHttpRequest code into the movie-code and do the request from there. Every client-side bonsai execution context (worker, iframe) does support that.

Upvotes: 1

Related Questions