sverweij / mscgen_js

text => sequence charts
https://mscgen.js.org
GNU General Public License v3.0
207 stars 25 forks source link

How to use mscgen_js to render data generated dynamiclly? #240

Closed charon4ever closed 8 years ago

charon4ever commented 8 years ago

Hello,I want to use mscgen_js to render data received from the server side on web page. I create a div element on web page. I first use the angular data binding like that:

<div class="mscgen_js"> {{data}} </div>

But failed to draw the picture,It seems that angular data binding conflicts with mscgen_js?? And then,I use angular jqlite like that:

<script> var mscEle=angular.element(document.querySelector("#mscEle")); mscEle.html($scope.data); </script>

But also fail to draw picture on the page. So,can you help me about how to solve this problem?Thanks a lot.

sverweij commented 8 years ago

=> are these assumptions correct?

If so, there's two things I can think of:

I'm not an angular developer - but it seems the pattern to integrate stuff in NG apps would be to make a directive (NG < 1.5) or a component (NG1.5+/ NG2) for this. It should be doable with the help of mscgenjs-core.

charon4ever commented 8 years ago

Thank you for replying. I did use mscgenjs-inpage.js script and I included the mscgenjs-inpage.js script with the defer attribute. When I use angular jqlite(jquery in angular): <div class="mscgen_js"></div>
<script> var mscEle=angular.element(document.querySelector("#mscEle")); mscEle.html($scope.data); </script> I can see the raw data in the web page like that: msc { ........ } The data esixts in the div element,but obviously it is not rendered correctly.I can only see the text but can not see the picture. Your advice is helpful and it will take me a short time to find the cause of the problem,but at first,can you give a an example of using mscgenjs-inpage.js to render dynamic data?

sverweij commented 8 years ago

Probably the content of the div is set to msc{...} until after page load.

To see what happens in slow motion: https://jsfiddle.net/sm8hpfuj/

If the div is updated before page load it probably looks closer to what you'd expect: https://jsfiddle.net/e5abd2yL/

So - what to do instead?

Rule of thumb

Some samples

I don't know enough of your specific environment (and of angular, t.b.h.) to be sure to give you an example that speaks to you.

You'll have to import the mscgenjs module somehow. There's a commonjs and a requirejs variant, both of which are in the mscgenjs npm module (repo: sverweij/mscgenjs-core).

// commonjs
var mscgenjs = require('mscgenjs');
// requirejs
require(['youe/path/to/mscgenjs/indexAMD.js'], function(mscgenjs){
    // your code here
});

When you have imported mscgenjs you can

Here's some some samples for using the root module directly:

// renders the given script in the (already existing) element with id=yourCoolId
mscgenjs.renderMsc (
  'msc { a,b; a=>>b[label="render this"; }', 
  {
    elementId: "yourCoolId"
  }
);

If you want to do error handling, or act on the created svg: provide a callback:

mscgenjs.renderMsc (
  'msc { a,b; a=>>b[label="render this"; }', 
  {
    elementId: "yourOtherCoolId"
  },
  handleRenderMscResult
);

function handleRenderMscResult(pError, pSuccess) {
  if (Boolean(pError)){
    console.log (pError);
  } else if (Boolean(pSuccess)){
    console.log ('That worked - cool!');
   // the svg is in the pSuccess argument 
  }
  console.log('Wat! Error nor success?');
}

The second parameter in the renderMsc call takes some options that influence rendering e.g.

mscgenjs.renderMsc (
  'a=>>b:render this;', 
  {
    elementId: "yourThirdCoolId",
    inputType: "msgenny", // language to parse - default "mscgen"; other accepted languages: "xu", "msgenny" and "json" 
    mirrorEntitiesOnBottom: true, // draws entities on both top and bottom of the chart - default false
    additionalTemplate: "lazy", // use a predefined template. E.g. "lazy" or "classic". Default empty
    includeSource: false, // whether the generated svg should include the source in a desc element
  },

HTH

Thanks for this question. The answer is so long only because I can't point to easily grokkable documentation on mscgenjs-core. I'll rectify that with this answer as a starting point somewhere in the near future.

charon4ever commented 8 years ago

Thank you very much for your answer! I changed to use mscgen-core instead of mscgen-inpage.js and it worked! Cause I'm not familiar with requirejs,it takes me some time to integrate requirejs into angular and luckily i succeed at last. Maybe in the future,the msngen_js could have an angular edition so that we can use this in angular much more easily.Thank you again for your kindness.

hari-kris commented 7 years ago

Now I am able to get the sequence diagram after page loading in angularjs.

index.html
<div id="__svg"   class="mscgen_js">

   </div>

app.js

$scope.generateChart = function () {
 $scope.queryLang = 'msc { ....}'; // 
mscgenjs.renderMsc (
      $scope.queryLang,
      {
        additionalTemplate: 'lazy',
        includeSource: false,
        elementId: '__svg',
      },
      handleRenderMscResult
    );
}

When I call the function for the first time, sequence diagram is generated when same function is called with different mscgen query language, new chart is not rendered. I went through atom live preview and online interpreter but could not follow. Am I missing anything.

There is no error in mscgen query language I checked in handleRenderMscResult function. How to get new result rendered. Can you please help me out.

sverweij commented 7 years ago

The first thing your function does is to change the global variable $scope.queryLang back to your initial sequence chart, so even if $scope.queryLang was changed before (e.g. when the field you bound it to changed) you'll reset it any time.

B.t.w. maybe you already found them but the README of mscgenjs/mscgenjs-core now contains better instructions for using mscgenjs-core than the original answer to this issue.