Custom Chart Stacked Bar

Bhupinder1
Giga Expert

Hi,

 

I wanted to create a custom assignment group stacked bar graph like the one listed in below link-

 

JFreeChart: Stacked Bar Chart Demo 4 : Bar Stacked Chart « Chart « Java

 

I'm not very familiar to JFree chart API but if anyone can help in creating the above in ServiceNow that would be great

 

Thanks

Bhupinder

1 ACCEPTED SOLUTION

Hi Kevin,



Thanks for response. But I have little different requirement here that goes-



Let me explain the graph I want to generate




1. Problems Created vs Closed Stacked on Assignment group


2. I'm able to generate garph for all Problems Created vs Closed (Attaching the image)


3. I need to stack on Assignment group for each bar in the above graph like Problems created should be stacked on Assignment group and same for Problems closed


4. As an aletrnative if we can group by Assignment group and for each assignment group if we can show Problems created vs closed that would also do the purpose


5. I'm attaching all the pieces of code that generate graph mentioned in step#2



Below is the graph for which I want to stack on against assignment group



Sample.png


I used custom chart reporting to build above graph and now want to extend the reporting further using Java JFree chart API. For the above graph I used the below piece of code-



Here's the code -



Data Generators


Trend of Open Problems Task


var opened = new SummaryTableWriter("problem_task", '');


  • opened.setTitle("Trend of Open Problems Task");
  • opened.setTrend('opened_at', 'month');
  1. current.summary = opened.generate();
  2. current.setWorkflow(false);
  3. current.update();


Trend of Closed Problems Task


var closed = new SummaryTableWriter("problem_task", '');


  1. closed.setTitle("Trend of Closed Problems Task");
  2. closed.setTrend('closed_at', 'month');
  3. current.summary = closed.generate();
  4. current.setWorkflow(false);
  5. current.update();


Renderer Script


//Get the sys_id values for the sys_report_summary table entries build by our generators


var openID = summary_sets.get("Trend of Open Problems Task");


var closedID = summary_sets.get("Trend of Closed Problems Task");



// Gets a utility class for dataset manipulation


var cu = new ChartUtil();


  1. cu.setTable('problem_task');
  2. cu.setColors("#FFDEAD,#7FFF00");


// Get the dataset for the Open incidents


var open = new ChartGenerator("bar");


  • open.setTable('problem_task');
  • open.setSummaryID(openID);

var ds = open.getDataset();



// Get the dataset for the Closed incidents and combine with the open incidents into


// a multi series dataset


var closed = new ChartGenerator("bar");


  1. closed.setTable('problem_task');
  2. closed.setSummaryID(closedID);

ds = cu.mergeDatasets(ds, "Created", closed.getDataset(), "Closed");



var chart = closed.getChart(ds);



// Change the spacing


  1. closed.setNoMargins();

// return our chart


answer = chart;


View solution in original post

5 REPLIES 5

servicenowkevin
ServiceNow Employee
ServiceNow Employee

bhupinder rajput, I think what you want to try is:


  1. Create a new report.
  2. Choose Trend Chart.
  3. Choose the table you need to report on. In the example I'll embed below, I used the kb_use table.
  4. Choose what you want to group by. I grouped by Topic. This lets me see which topics are being viewed more often.
  5. Set your trend field. I chose Created and Month.
  6. Add filters as needed. I filtered to only customer or partner views.
  7. Click Run.
  8. If the report is what you're looking for, save.

ExternalViews.png



Did that help?


Hi Kevin,



Thanks for response. But I have little different requirement here that goes-



Let me explain the graph I want to generate




1. Problems Created vs Closed Stacked on Assignment group


2. I'm able to generate garph for all Problems Created vs Closed (Attaching the image)


3. I need to stack on Assignment group for each bar in the above graph like Problems created should be stacked on Assignment group and same for Problems closed


4. As an aletrnative if we can group by Assignment group and for each assignment group if we can show Problems created vs closed that would also do the purpose


5. I'm attaching all the pieces of code that generate graph mentioned in step#2



Below is the graph for which I want to stack on against assignment group



Sample.png


I used custom chart reporting to build above graph and now want to extend the reporting further using Java JFree chart API. For the above graph I used the below piece of code-



Here's the code -



Data Generators


Trend of Open Problems Task


var opened = new SummaryTableWriter("problem_task", '');


  • opened.setTitle("Trend of Open Problems Task");
  • opened.setTrend('opened_at', 'month');
  1. current.summary = opened.generate();
  2. current.setWorkflow(false);
  3. current.update();


Trend of Closed Problems Task


var closed = new SummaryTableWriter("problem_task", '');


  1. closed.setTitle("Trend of Closed Problems Task");
  2. closed.setTrend('closed_at', 'month');
  3. current.summary = closed.generate();
  4. current.setWorkflow(false);
  5. current.update();


Renderer Script


//Get the sys_id values for the sys_report_summary table entries build by our generators


var openID = summary_sets.get("Trend of Open Problems Task");


var closedID = summary_sets.get("Trend of Closed Problems Task");



// Gets a utility class for dataset manipulation


var cu = new ChartUtil();


  1. cu.setTable('problem_task');
  2. cu.setColors("#FFDEAD,#7FFF00");


// Get the dataset for the Open incidents


var open = new ChartGenerator("bar");


  • open.setTable('problem_task');
  • open.setSummaryID(openID);

var ds = open.getDataset();



// Get the dataset for the Closed incidents and combine with the open incidents into


// a multi series dataset


var closed = new ChartGenerator("bar");


  1. closed.setTable('problem_task');
  2. closed.setSummaryID(closedID);

ds = cu.mergeDatasets(ds, "Created", closed.getDataset(), "Closed");



var chart = closed.getChart(ds);



// Change the spacing


  1. closed.setNoMargins();

// return our chart


answer = chart;


dartx21
Kilo Contributor

Bhupinder I have been trying to do something similar, but bascially add more bar graphs so bascially 3 bar graph chart in one chart. Currently from all the resource I have done the only way to do what you want is using Jfreechart API. Unfortunately, if you want more advance graphs custom charts is not very friendly with people that have limited scripting knowledge. You can take a look at all these functions by looking it up in the script includes. I provided a link and will help you better understand. I believe the chart this person created is what you are looking for. So if you have very good scipting skills this will point you in the right direction.   Look at the Custom Charts: A Use Case Section



http://www.cloudsherpas.com/partner-servicenow/servicenow-tech-tuesdays-tracking-and-analyzing-data-...


Hi Dart,



Even I looked at that particular example which indeed is very helpful and also I got the script include used in that particular example which I'm listing below. Can you please look at this code and suggest me how could I use this code in the Renderer script for my case listed above?



var CSChartGenerator = Class.create();



  1. CSChartGenerator.prototype = Object.extendsObject(ChartGenerator, {


          getStackedBarChart : function(title, data, barGroups, domainLabel, rangeLabel) {


              // Data must be an array of objects. Each object represents a bar section


              // and should have this format:


              //


              // obj.columnKey = domain value label;


              // obj.rowKey = bar section name;


              // obj.rowKeyLabel = bar section label;


              // obj.rowKeyLegendLabel = bar section legend label;


              // obj.value = value for bar section;


              // obj.color = color for bar section (java Color);


              // obj.barGroup = subcategory if multiple charts to be shown;



              // Create the report dataset


              var dataset = new Packages.org.jfree.data.category.DefaultCategoryDataset();


              for (var i = 0; i < data.length; i++) {


                  var obj = data[i];


dataset.addValue(obj.value, obj.rowKeyLabel, obj.columnKey);   // value, rowKey, columnKey


              }



              // Create a stacked bar chart


              var chart = Packages.org.jfree.chart.ChartFactory.createStackedBarChart(title, domainLabel, rangeLabel, dataset,


Packages.org.jfree.chart.plot.PlotOrientation.VERTICAL, true, true, false);



chart.setBackgroundPaint(Packages.java.awt.Color.WHITE);



              var renderer = new Packages.org.jfree.chart.renderer.category.GroupedStackedBarRenderer();


             


              if (barGroups && barGroups.length > 0) {


                  var obj = barGroups[0];


                  var map = new Packages.org.jfree.data.KeyToGroupMap(obj.barGroup);


              }



              // Tell the chart which task type belongs to which group


              for (var i = 0; i < data.length; i++) {


                  var obj = data[i];


map.mapKeyToGroup(obj.rowKeyLabel, obj.barGroup);


              }



renderer.setSeriesToGroupMap(map);



              // Tell the chart which color to use for each task type


              // We want the colors to be the same for each task type regardless of group


              for (i = 0; i < data.length; i++) {


                  var obj = data[i];


renderer.setSeriesPaint(i, obj.color);


              }



              // Tell the chart to show a tool tip - this will be the assignment group, task type and count


              var toolTipGenerator = new Packages.org.jfree.chart.labels.StandardCategoryToolTipGenerator();


renderer.setBaseToolTipGenerator(toolTipGenerator);



renderer.setItemMargin(0.0);



              // Set up the bottom axis labels


              var domainAxis = new Packages.org.jfree.chart.axis.SubCategoryAxis(domainLabel);


              if (barGroups && barGroups.length > 0) {


domainAxis.setCategoryMargin(0.05);


                  for (i = 0; i < barGroups.length; i++) {


                      obj = barGroups[i];


domainAxis.addSubCategory(obj.label);


                  }


              }



              var plot = chart.getPlot();


plot.setDomainAxis(domainAxis);


plot.setRenderer(renderer);



              // Add the legend - we want just the task type to show, no indication of opened vs closed


plot.setFixedLegendItems(this._createLegendItems(data));


              return chart;


          },



          setToolTipLabel : function(chart, toolTipGenerator) {


              var renderer = chart.getPlot().getRenderer();


              renderer.setBaseToolTipGenerator(toolTipGenerator);


          },



          setCategoryItemLabel : function(chart, categoryItemLabel) {


              var renderer = chart.getPlot().getRenderer();


renderer.setBaseItemLabelGenerator(categoryItemLabel);


              renderer.setBaseItemLabelsVisible(true);


renderer.setBasePositiveItemLabelPosition(new Packages.org.jfree.chart.labels.ItemLabelPosition(


Packages.org.jfree.chart.labels.ItemLabelAnchor.OUTSIDE12, Packages.org.jfree.ui.TextAnchor.BASELINE_CENTER));


          },



          _createLegendItems : function(data) {


              var done = {};


              gs.log("DATA: " + data.length);


              var result = new Packages.org.jfree.chart.LegendItemCollection();


              for (var i = 0; i < data.length; i++) {


                  var dataObj = data[i];


                  if (done[dataObj.rowKey]) {


                      continue;


                  }


                  var item = new Packages.org.jfree.chart.LegendItem(dataObj.rowKeyLegendLabel, dataObj.rowKeyLegendLabel, dataObj.rowKeyLegendLabel,


                          dataObj.rowKeyLegendLabel, new Packages.java.awt.Rectangle(10, 10), dataObj.color);


result.add(item);


done[dataObj.rowKey] = true;


              }


              return result;


          },


         


          type : "CSChartGenerator"


      });