What is the best Chart package in ERPNext?

In the frappe charts we only have some types like bar, line, pie etc…
But I want to add bubble chart.

I tried chart.js package but I couldn’t be able to integrate it with the ErpNext.

is there any way we can use bubble chart in erpnext?

BTW, I’m using page to displaying the chart.
Frappe version 14

@Robot you can use any other plugin . I successfully installed amcharts . just include the script packages in the html field . and copy js code .

Hi @bahaou
Thanks for the response.

I’m facing little hard to configure this, if there’s a chance can you share any of your source code where I can see how you’re configured or any other documentation? That’d be really helpful.

@Robot write this as html (copy scripts from the website ).
the last one is our chart div


next open demo page , select any chart . copy js and paste it in script box . nothing needs to be changed .

and voila you get the chart running .

next for your data , just update the js file

3 Likes

I have tried it with website, It is working. Thank you @bahaou

BTW, Have you ever implemented this with page? Because I want to implement this with page.
I have tried that too but couldn’t be able to configure properly.

Facing am5 is not defined issue

request.js:298 ReferenceError: am5 is not defined
    at frappe.pages.my-segmentor-custome.on_page_load (my_segmentor_custome.js:88:2)
    at Page2.trigger_page_event (pageview.js:102:15)
    at new Page2 (pageview.js:89:8)
    at pageview.js:52:6
    at Object.callback (pageview.js:36:6)
    at Object.callback [as success_callback] (request.js:85:16)
    at 200 (request.js:128:34)
    at Object.<anonymous> (request.js:294:6)
    at fire (jquery.js:3500:31)
    at Object.fireWith [as resolveWith] (jquery.js:3630:7)

I have inspected the page, the script is in head. but still facing the error

@Robot open console and type am5 . is it there ?

@bahaou Yes, it is there.

@Robot then it should work . you copied same js code ?

Hi @bahaou It is solved.
The issue was am5 rendered before the script tag assignment.

So, I simply put setTimeout for 2 sec, Now it is working fine.
Thank you so much.

@bahaou , What is the use of this, can you pls explain?, As it is a webpage, we can show in website. but can we use this chart inside our workspace?
Sorry for the immature question, newbie here and learning…

@ErpnextRaja yes you can using custom blocks , or in doctypes using html fields .

1 Like

Thank you @bahaou … I tried wepage it is working fine. But not working in custom block. the same code. Below is HTML

<script src="https://cdn.amcharts.com/lib/version/5.5.7/index.js"></script>
<script src="https://cdn.amcharts.com/lib/version/5.5.7/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/version/5.5.7/themes/Animated.js"></script>
<script src="https://cdn.amcharts.com/lib/version/5.5.7/locales/de_DE.js"></script>
<div id="chartdiv" style="width:50%;height:500px"></div>

and javascript

am5.ready(function() {

// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");

// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([
  am5themes_Animated.new(root)
]);

var data = [{
  name: "Monica",
  steps: 45688,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/monica.jpg"
  }
}, {
  name: "Joey",
  steps: 35781,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/joey.jpg"
  }
}, {
  name: "Ross",
  steps: 25464,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/ross.jpg"
  }
}, {
  name: "Phoebe",
  steps: 18788,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/phoebe.jpg"
  }
}, {
  name: "Rachel",
  steps: 15465,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/rachel.jpg"
  }
}, {
  name: "Chandler",
  steps: 11561,
  pictureSettings: {
    src: "https://www.amcharts.com/wp-content/uploads/2019/04/chandler.jpg"
  }
}];

// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
var chart = root.container.children.push(
  am5xy.XYChart.new(root, {
    panX: false,
    panY: false,
    wheelX: "none",
    wheelY: "none",
    paddingBottom: 50,
    paddingTop: 40
  })
);

// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/

var xRenderer = am5xy.AxisRendererX.new(root, {});
xRenderer.grid.template.set("visible", false);

var xAxis = chart.xAxes.push(
  am5xy.CategoryAxis.new(root, {
    paddingTop:40,
    categoryField: "name",
    renderer: xRenderer
  })
);


var yRenderer = am5xy.AxisRendererY.new(root, {});
yRenderer.grid.template.set("strokeDasharray", [3]);

var yAxis = chart.yAxes.push(
  am5xy.ValueAxis.new(root, {
    min: 0,
    renderer: yRenderer
  })
);

// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
var series = chart.series.push(
  am5xy.ColumnSeries.new(root, {
    name: "Income",
    xAxis: xAxis,
    yAxis: yAxis,
    valueYField: "steps",
    categoryXField: "name",
    sequencedInterpolation: true,
    calculateAggregates: true,
    maskBullets: false,
    tooltip: am5.Tooltip.new(root, {
      dy: -30,
      pointerOrientation: "vertical",
      labelText: "{valueY}"
    })
  })
);

series.columns.template.setAll({
  strokeOpacity: 0,
  cornerRadiusBR: 10,
  cornerRadiusTR: 10,
  cornerRadiusBL: 10,
  cornerRadiusTL: 10,
  maxWidth: 50,
  fillOpacity: 0.8
});

var currentlyHovered;

series.columns.template.events.on("pointerover", function (e) {
  handleHover(e.target.dataItem);
});

series.columns.template.events.on("pointerout", function (e) {
  handleOut();
});

function handleHover(dataItem) {
  if (dataItem && currentlyHovered != dataItem) {
    handleOut();
    currentlyHovered = dataItem;
    var bullet = dataItem.bullets[0];
    bullet.animate({
      key: "locationY",
      to: 1,
      duration: 600,
      easing: am5.ease.out(am5.ease.cubic)
    });
  }
}

function handleOut() {
  if (currentlyHovered) {
    var bullet = currentlyHovered.bullets[0];
    bullet.animate({
      key: "locationY",
      to: 0,
      duration: 600,
      easing: am5.ease.out(am5.ease.cubic)
    });
  }
}

var circleTemplate = am5.Template.new({});

series.bullets.push(function (root, series, dataItem) {
  var bulletContainer = am5.Container.new(root, {});
  var circle = bulletContainer.children.push(
    am5.Circle.new(
      root,
      {
        radius: 34
      },
      circleTemplate
    )
  );

  var maskCircle = bulletContainer.children.push(
    am5.Circle.new(root, { radius: 27 })
  );

  // only containers can be masked, so we add image to another container
  var imageContainer = bulletContainer.children.push(
    am5.Container.new(root, {
      mask: maskCircle
    })
  );

  var image = imageContainer.children.push(
    am5.Picture.new(root, {
      templateField: "pictureSettings",
      centerX: am5.p50,
      centerY: am5.p50,
      width: 60,
      height: 60
    })
  );

  return am5.Bullet.new(root, {
    locationY: 0,
    sprite: bulletContainer
  });
});

// heatrule
series.set("heatRules", [
  {
    dataField: "valueY",
    min: am5.color(0xe5dc36),
    max: am5.color(0x5faa46),
    target: series.columns.template,
    key: "fill"
  },
  {
    dataField: "valueY",
    min: am5.color(0xe5dc36),
    max: am5.color(0x5faa46),
    target: circleTemplate,
    key: "fill"
  }
]);

series.data.setAll(data);
xAxis.data.setAll(data);

var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {}));
cursor.lineX.set("visible", false);
cursor.lineY.set("visible", false);

cursor.events.on("cursormoved", function () {
  var dataItem = series.get("tooltip").dataItem;
  if (dataItem) {
    handleHover(dataItem);
  } else {
    handleOut();
  }
});

// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
chart.appear(1000, 100);

}); // end am5.ready()

It is giving empty blog. no chart in dashboard. can you pls guide me where i am wrong…

To interact with above HTML, you’ll have to use root_element s a parent selector.

In your javascript section, start with

let myChart = root_element.querySelector("#chartdiv");
let root = am5.Root.new(myChart);

@kevingee thanks for your reply. Added in script… but still not showing in custom block.
@bahaou I tried am5 in console. it is loaded… Showing error am5 is not defined. then i tried like @Robot mentioned set timeout as below. still not chart not showing up.

setTimeout(() => {
  console.log("Delayed for 2 second.");
}, "2000");

am5.ready(function() {

var root = am5.Root.new("chartdiv");



root.setThemes([
  am5themes_Animated.new(root)
]);

@ErpnextRaja if am5 is still not defined try to add the scripts in www/app.html file .

@ErpnextRaja Could you check If there is any error in your console?