ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  x Axis labels as legend
Posted by Prashanth on Aug-14-2012 14:21
Hi,

Can i hide the xaxis labels and put them as legends instead for a bar chart?

can you post the code on how i can achieve this. since the xaxis labels are way too long and i want all of them to be displayed

Thanks
Prashanth

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-15-2012 00:38
Hi Prashanth,

I assume you are using a Multi-Color Bar Chart (addBarLayer3). In this case, you can use something like (in C#/Java):

c.addBarLayer3(myData, myColors, myBarNames);

With the above code, if you add a legend box (using BaseChart.addLegend), the bar names will appear in the legend box.

You may use a different set of labels for the x-axis if you like (eg. using a short form of the names, or just use empty space).

Hope this can help.

Regards
Peter Kwan

  Re: x Axis labels as legend
Posted by Prashanth on Aug-16-2012 14:03
Can i use the same option with
BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom);
for Waterfall chart

then add BaseChart.addlegend

How can i achieve this for a waterfall chart?

Thanks
Prashanth

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-17-2012 08:33
Hi Prashanth,

Yes. The addBoxWhiskerLayer2 method also allows you to provide an array of text strings to be used as names in the legend box. Please refer to the documentation for XYChart.addBoxWhiskerLayer2 for details. For the 3rd to 7th parameters, if you do not use them, you may just put in the default value as mentioned in the documentation (the Empty_Array in C#/Java is the keyword null).

Hope this can help.

Regards
Peter Kwan

  Re: x Axis labels as legend
Posted by Prashanth on Aug-20-2012 15:09
I tried passing the label names and setting the xaxis labels as empty space. then
i set BaseChart.addlegend, but the legends are not appearing do you know what i might be wrong?

I am using chartdirector for java

Thanks
Prashanth

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-21-2012 01:05
Hi Prashanth,

Have you passed the legend names (the labels) to ChartDirector in your addBoxWhiskerLayer2 method call? The code should be like:

c.addLegend(75, 10, false);

BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(Q3Data, Q1Data, Q4Data, Q0Data, Q2Data, null, 0.5, labels);

If the above still does not solve the problem, is it possible to inform me the charting part of your code. It is not easy to know what might be the issue if I cannot see your code. If you cannot post your code in a public forum, you may email me at pkwan@advsofteng.net

Regards
Peter Kwan

  Re: x Axis labels as legend
Posted by Prashanth on Aug-21-2012 14:11
Attachments:
thats exactly what i have done

            XYChart c = new XYChart(600, 350, 0xFFFFFF, 0xFFFFFF, 0);
            // Add a line layer for the pareto line
              LineLayer lineLayer = c.addLineLayer2();
              // Add the pareto line using deep blue (0000ff) as the color, with circle
              // symbols
              lineLayer.addDataSet(lineData.result(), 0x000000).setDataSymbol(Chart.CircleShape, 9, 0x000000, 0x000000);
              // Set the line width to 2 pixel
              lineLayer.setLineWidth(2);
              // Bind the line layer to the secondary (right) y-axis.
              lineLayer.setUseYAxis2();
              c.yAxis2().setTitle("Cumulative % of Total Benefits");
              c.yAxis2().setLabelFormat("{value}%");
                  // The top side of the bars in a waterfall chart is the accumulated data. We
                   // use the ChartDirector ArrayMath utility to accumulate the data. The
                   // "total" is handlsed by inserting a zero point at the end before
                   // accumulation (after accumulation it will become the total).
                   double[] boxTop = new ArrayMath(data).insert2(0, 1).acc().result();

                   // The botom side of the bars is just the top side of the previous bar. So we
                   // shifted the top side data to obtain the bottom side data.
                   double[] boxBottom = new ArrayMath(boxTop).shift(1, 0).result();

                   // The last point (total) is different. Its bottom side is always 0.
                   boxBottom[boxBottom.length - 1] = 0;

                   // Create a XYChart object of size 500 x 280 pixels. Set background color to
                   // light blue (ccccff), with 1 pixel 3D border effect.

                   // Add a title to the chart using 13 points Arial Bold Itatic font, with
                   // white (ffffff) text on a deep blue (0x80) background
                //   c.addTitle("Top Business Benefits", "Arial Bold", 13, 0x000000);

                   // Set the plotarea at (55, 50) and of size 430 x 215 pixels. Use alternative
                   // white/grey background.
                   c.setPlotArea(85, 45, 450, 215, Chart.Transparent, Chart.Transparent);

                   // Set the labels on the x axis using Arial Bold font
                   c.xAxis().setLabels(labels1).setFontStyle("Arial",8);
                   c.xAxis().setIndent(true);

                   // Set the x-axis ticks and grid lines to be between the bars
                   c.xAxis().setTickOffset(0.5);

                   // Use Arial Bold as the y axis label font
                   c.yAxis().setLabelStyle("Arial",8);
            c.addLegend(50, 300, false, "Arial", 8).setBackground(Chart.Transparent);
                   // Add a multi-color box-whisker layer to represent the waterfall bars
                   BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, null, 0.5, labels);
                   layer.setBoxColors(hexcodes);
                   layer.setBorderColor(Chart.Transparent);

dont know what could be the problem

I am attaching the image generated

Thanks
Prashanth
Target Corporation_20120820__1001_top_waterfall_ben.jpg

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-22-2012 19:14
Attachments:
Hi Prashanth,

I have just tried your exact code with some hard coded data. It works normally in my case. I have attached my test code for your reference.

If the legend box does not appear in your case, is it possible that you labels array are empty or contains only empty text strings? For example, if you set labels1 to be equal to labels, and then set the contents of labels1 to empty, then it will also set the contents of labels to empty. (labels1 should be set to a clone of labels, not set to equal to labels.)

If you need further help, is it possible to attach the complete code with hard coded data, so I may test it?

Regards
Peter Kwan
waterfall.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import ChartDirector.*;

public class waterfall implements DemoModule
{
    //Name of demo program
    public String toString() { return "Waterfall Chart"; }

    //Number of charts produced in this demo
    public int getNoOfCharts() { return 1; }

    //Main code for creating charts
    public void createChart(ChartViewer viewer, int index)
    {
        // 4 data points to represent the cash flow for the Q1 - Q4
        double[] data = {230, 140, 220, 330, 150};
		ArrayMath lineData = new ArrayMath(data);
		lineData.acc();
		double scaleFactor = lineData.max() / 100;
		if (scaleFactor == 0) {
			// Avoid division by zero error for zero data
			scaleFactor = 1;
		}
		lineData.div2(scaleFactor);

        // We want to plot a waterfall chart showing the 4 quarters as well as the
        // total
        String[] labels = {"Product 1", "Product 2", "Product 3", "Product 4",
            "Product 5", "Total"};
		String[] labels1 = null;
 
		XYChart c = new XYChart(600, 350, 0xFFFFFF, 0xFFFFFF, 0);
	   // Add a line layer for the pareto line
		 LineLayer lineLayer = c.addLineLayer2();
		 // Add the pareto line using deep blue (0000ff) as the color, with circle
		 // symbols
		 lineLayer.addDataSet(lineData.result(), 0x000000).setDataSymbol(Chart.CircleShape, 9, 0x000000, 0x000000);
		 // Set the line width to 2 pixel
		 lineLayer.setLineWidth(2);
		 // Bind the line layer to the secondary (right) y-axis.
		 lineLayer.setUseYAxis2();
		 c.yAxis2().setTitle("Cumulative % of Total Benefits");
		 c.yAxis2().setLabelFormat("{value}%");
			 // The top side of the bars in a waterfall chart is the accumulated data. We
			  // use the ChartDirector ArrayMath utility to accumulate the data. The
			  // "total" is handlsed by inserting a zero point at the end before
			  // accumulation (after accumulation it will become the total).
			  double[] boxTop = new ArrayMath(data).insert2(0, 1).acc().result();

			  // The botom side of the bars is just the top side of the previous bar. So we
			  // shifted the top side data to obtain the bottom side data.
			  double[] boxBottom = new ArrayMath(boxTop).shift(1, 0).result();

			  // The last point (total) is different. Its bottom side is always 0.
			  boxBottom[boxBottom.length - 1] = 0;

			  // Create a XYChart object of size 500 x 280 pixels. Set background color to
			  // light blue (ccccff), with 1 pixel 3D border effect.

			  // Add a title to the chart using 13 points Arial Bold Itatic font, with
			  // white (ffffff) text on a deep blue (0x80) background
		   //   c.addTitle("Top Business Benefits", "Arial Bold", 13, 0x000000);

			  // Set the plotarea at (55, 50) and of size 430 x 215 pixels. Use alternative
			  // white/grey background.
			  c.setPlotArea(85, 45, 450, 215, Chart.Transparent, Chart.Transparent);

			  // Set the labels on the x axis using Arial Bold font
			  c.xAxis().setLabels(labels1).setFontStyle("Arial",8);
			  c.xAxis().setIndent(true);

			  // Set the x-axis ticks and grid lines to be between the bars
			  c.xAxis().setTickOffset(0.5);

			  // Use Arial Bold as the y axis label font
			  c.yAxis().setLabelStyle("Arial",8);
	   c.addLegend(50, 300, false, "Arial", 8).setBackground(Chart.Transparent);
			  // Add a multi-color box-whisker layer to represent the waterfall bars
			  BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, null, 0.5, labels);
			  //layer.setBoxColors(hexcodes);
			  layer.setBorderColor(Chart.Transparent);

        // Output the chart
        viewer.setChart(c);

        //include tool tip for the chart
        viewer.setImageMap(c.getHTMLImageMap("clickable", "",
            "title='{xLabel}: {={top}-{bottom}} millions'"));
    }

    //Allow this module to run as standalone program for easy testing
    public static void main(String[] args)
    {
        //Instantiate an instance of this demo module
        DemoModule demo = new waterfall();

        //Create and set up the main window
        JFrame frame = new JFrame(demo.toString());
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);} });
        frame.getContentPane().setBackground(Color.white);

        // Create the chart and put them in the content pane
        ChartViewer viewer = new ChartViewer();
        demo.createChart(viewer, 0);
        frame.getContentPane().add(viewer);

        // Display the window
        frame.pack();
        frame.setVisible(true);
    }
}


  Re: x Axis labels as legend
Posted by Prashanth on Aug-23-2012 17:18
this is the code with hardcoded data. the difference is I am writing the image to a file.
and this code does not work i dont know why.

Thanks,
Prashanth

double[] data = new double[]{230, 140, 220, 330, 150};
             String[]labels = new String[]{"Product 1", "Product 2", "Product 3", "Product 4", "Product 5", "Total"};

     String labels1[] = null;

            ArrayMath lineData = new ArrayMath(data);
          lineData.acc();
          double scaleFactor = lineData.max() / 100;
          if (scaleFactor == 0) {
              // Avoid division by zero error for zero data
              scaleFactor = 1;
          }
          lineData.div2(scaleFactor);


            ChartViewer viewer = new ChartViewer();
            XYChart c = new XYChart(600, 350, 0xFFFFFF, 0xFFFFFF, 0);
            // Add a line layer for the pareto line
              LineLayer lineLayer = c.addLineLayer2();
              // Add the pareto line using deep blue (0000ff) as the color, with circle
              // symbols
              lineLayer.addDataSet(lineData.result(), 0x000000).setDataSymbol(Chart.CircleShape, 9, 0x000000, 0x000000);
              // Set the line width to 2 pixel
              lineLayer.setLineWidth(2);
              // Bind the line layer to the secondary (right) y-axis.
              lineLayer.setUseYAxis2();
              c.yAxis2().setTitle("Cumulative % of Total Benefits");
              c.yAxis2().setLabelFormat("{value}%");
                  // The top side of the bars in a waterfall chart is the accumulated data. We
                   // use the ChartDirector ArrayMath utility to accumulate the data. The
                   // "total" is handlsed by inserting a zero point at the end before
                   // accumulation (after accumulation it will become the total).
                   double[] boxTop = new ArrayMath(data).insert2(0, 1).acc().result();

                   // The botom side of the bars is just the top side of the previous bar. So we
                   // shifted the top side data to obtain the bottom side data.
                   double[] boxBottom = new ArrayMath(boxTop).shift(1, 0).result();

                   // The last point (total) is different. Its bottom side is always 0.
                   boxBottom[boxBottom.length - 1] = 0;

                   // Create a XYChart object of size 500 x 280 pixels. Set background color to
                   // light blue (ccccff), with 1 pixel 3D border effect.

                   // Add a title to the chart using 13 points Arial Bold Itatic font, with
                   // white (ffffff) text on a deep blue (0x80) background
                //   c.addTitle("Top Business Benefits", "Arial Bold", 13, 0x000000);

                   // Set the plotarea at (55, 50) and of size 430 x 215 pixels. Use alternative
                   // white/grey background.
                   c.setPlotArea(85, 45, 450, 215, Chart.Transparent, Chart.Transparent);
                //    c.addLegend(5, 5, true, "Arial Bold", 11).setBackground(Chart.Transparent);

                   // Set the labels on the x axis using Arial Bold font
                   c.xAxis().setLabels(labels1).setFontStyle("Arial",8);
                   c.xAxis().setIndent(true);

                   // Set the x-axis ticks and grid lines to be between the bars
                   c.xAxis().setTickOffset(0.5);

                   // Use Arial Bold as the y axis label font
                   c.yAxis().setLabelStyle("Arial",8);

                   if (currency !=null && currency.equals("USD")){
                        if (currencyUnitsStr.indexOf("in Millions")>-1)
                        c.yAxis().setLabelFormat("$ {value|2,.~}");
                        else
                            c.yAxis().setLabelFormat("$ {value|0,.~}");
                    }else{
                        if (currencyUnitsStr.indexOf("in Millions")>-1)
                        c.yAxis().setLabelFormat("{value|2,.~}");
                        else
                            c.yAxis().setLabelFormat("{value|0,.~}");
                    }

   c.addLegend(50, 300, false, "Arial", 8).setBackground(Chart.Transparent);

                   // Add a multi-color box-whisker layer to represent the waterfall bars
                   BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, null, 0.5, labels);
            int [] hexcodes = {0xFF0000,0x808080,0x000000,0x777777,0xCCCCFF,0x006600,0x009999 ,0x666666,0x333300,0x667263,0x545F75,0x4D4D4D  };
                   layer.setBoxColors(hexcodes);
                   layer.setBorderColor(Chart.Transparent);
                   viewer.setChart(c);

                viewer.setImage(c.makeImage());
                Image image=viewer.getImage();
                int w = image.getWidth(null);
                int h = image.getHeight(null);
                BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                Graphics2D g2 = bi.createGraphics();
                g2.drawImage(image, 0, 0, null);
                g2.dispose();
                try
                {
                    ImageIO.write(bi, "png", new File("c:\\filename.jpg"));
                }
                catch(IOException ioe)
                {
                    System.out.println("write: " + ioe.getMessage());
                }

  Re: x Axis labels as legend
Posted by Prashanth on Aug-23-2012 17:20
double[] data = new double[]{230, 140, 220, 330, 150};
             String[]labels = new String[]{"Product 1", "Product 2", "Product 3", "Product 4", "Product 5", "Total"};

     String labels1[] = null;

            ArrayMath lineData = new ArrayMath(data);
          lineData.acc();
          double scaleFactor = lineData.max() / 100;
          if (scaleFactor == 0) {
              // Avoid division by zero error for zero data
              scaleFactor = 1;
          }
          lineData.div2(scaleFactor);


            ChartViewer viewer = new ChartViewer();
            XYChart c = new XYChart(600, 350, 0xFFFFFF, 0xFFFFFF, 0);
            // Add a line layer for the pareto line
              LineLayer lineLayer = c.addLineLayer2();
              // Add the pareto line using deep blue (0000ff) as the color, with circle
              // symbols
              lineLayer.addDataSet(lineData.result(), 0x000000).setDataSymbol(Chart.CircleShape, 9, 0x000000, 0x000000);
              // Set the line width to 2 pixel
              lineLayer.setLineWidth(2);
              // Bind the line layer to the secondary (right) y-axis.
              lineLayer.setUseYAxis2();
              c.yAxis2().setTitle("Cumulative % of Total Benefits");
              c.yAxis2().setLabelFormat("{value}%");
                  // The top side of the bars in a waterfall chart is the accumulated data. We
                   // use the ChartDirector ArrayMath utility to accumulate the data. The
                   // "total" is handlsed by inserting a zero point at the end before
                   // accumulation (after accumulation it will become the total).
                   double[] boxTop = new ArrayMath(data).insert2(0, 1).acc().result();

                   // The botom side of the bars is just the top side of the previous bar. So we
                   // shifted the top side data to obtain the bottom side data.
                   double[] boxBottom = new ArrayMath(boxTop).shift(1, 0).result();

                   // The last point (total) is different. Its bottom side is always 0.
                   boxBottom[boxBottom.length - 1] = 0;

                   // Create a XYChart object of size 500 x 280 pixels. Set background color to
                   // light blue (ccccff), with 1 pixel 3D border effect.

                   // Add a title to the chart using 13 points Arial Bold Itatic font, with
                   // white (ffffff) text on a deep blue (0x80) background
                //   c.addTitle("Top Business Benefits", "Arial Bold", 13, 0x000000);

                   // Set the plotarea at (55, 50) and of size 430 x 215 pixels. Use alternative
                   // white/grey background.
                   c.setPlotArea(85, 45, 450, 215, Chart.Transparent, Chart.Transparent);
                //    c.addLegend(5, 5, true, "Arial Bold", 11).setBackground(Chart.Transparent);

                   // Set the labels on the x axis using Arial Bold font
                   c.xAxis().setLabels(labels1).setFontStyle("Arial",8);
                   c.xAxis().setIndent(true);

                   // Set the x-axis ticks and grid lines to be between the bars
                   c.xAxis().setTickOffset(0.5);

                   // Use Arial Bold as the y axis label font
                   c.yAxis().setLabelStyle("Arial",8);

                 c.addLegend(50, 300, false, "Arial", 8).setBackground(Chart.Transparent);

                   // Add a multi-color box-whisker layer to represent the waterfall bars
                   BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, null, 0.5, labels);
            int [] hexcodes = {0xFF0000,0x808080,0x000000,0x777777,0xCCCCFF,0x006600,0x009999 ,0x666666,0x333300,0x667263,0x545F75,0x4D4D4D  };
                   layer.setBoxColors(hexcodes);
                   layer.setBorderColor(Chart.Transparent);
                   viewer.setChart(c);

                viewer.setImage(c.makeImage());
                Image image=viewer.getImage();
                int w = image.getWidth(null);
                int h = image.getHeight(null);
                BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                Graphics2D g2 = bi.createGraphics();
                g2.drawImage(image, 0, 0, null);
                g2.dispose();
                try
                {
                    ImageIO.write(bi, "png", new File("c:\\filename.jpg"));
                }
                catch(IOException ioe)
                {
                    System.out.println("write: " + ioe.getMessage());
                }

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-24-2012 00:05
Hi Prashanth,

I have found the cause of the problem.

Instead of using:

BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, null, 0.5, labels);
layer.setBoxColors(hexcodes);

Please use:

BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom,  null, null, null, hexcodes, 0.5, labels);

or you may use:

BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom);
layer.setBoxColors(hexcodes, labels);

The addBoxWhiskerLayer2 allows you to specify the colors and the names. If for some reason you want to specify the colors and the names later, you can use the BoxWhiskerLayer.setBoxColors method.

However, if you just call WhiskerLayer.setBoxColors with the colors only, the names parameter will default to null, which means there are no names. This removes the legend entries.

Passing both the colors and names using addBoxWhiskerLayer2 or setBoxColors solves the problem.

Hope this can help.

Regards
Peter Kwan

  Re: x Axis labels as legend
Posted by Prashanth on Aug-24-2012 02:19
Attachments:
Thanks Kwan

Another query regarding labels for sectors in pie chart.
How do i wrap labels in when the text is too long. also in the attached images you can see that either the labels get cut or they or not wrapped properly since i insert the newline character in the label after certain character to wrap the label to the next line. in which case the word might get broken. Is there a way to do this using the api in chartdirector.
SYSCO Corporation_20120822__1001_ben_cat.jpg
SYSCO Corporation_20120814__1001_investments_category.jpg

  Re: x Axis labels as legend
Posted by Peter Kwan on Aug-24-2012 23:49
Hi Prashanth,

If you would like to insert the newline character yourself, I suggest your code goes to the character you want to insert the newline, and then search backwards for the nearest space character, and insert the newline there. This ensures the newline only breaks the text at a word boundary.

If you would like ChartDirector to wrap the text for you, you may use TextBox.setMaxWidth to tell ChartDirector the maxmium width of the textbox you would like to have. If the text is longer than the maximum width, ChartDirector will wrap the text into multiple lines. For example:

//wrap text if longer than 150 pixels
c.setLabelStyle("Arial", 8, 0x000000).setMaxWidth(150);

Hope this can help.

Regards
Peter Kwan

  Re: x Axis labels as legend
Posted by cumulative % of total on top of the boxes (waterfall chart) on Sep-13-2012 20:56
Hi Kwan,

with respect to the above waterfall chart is it possible to set the accumulated % of the total value on top of the boxes. can you let me know how to set the DataLabelFormat so that the waterfall chart shows cumulative % of the totals on top of the boxes?

1) how to set the Data label to show accumulated % values for the boxes
2) align it on top of the boxes


Thanks
Prashanth

  Re: x Axis labels as legend
Posted by Peter Kwan on Sep-14-2012 00:28
Hi Prashanth,

You may use something like:

//I assume the lineData is the percentage you want
layer.addExtraField2(lineData.result());
//Display the extra field on top of the bars
layer.setDataLabelFormat("{field0|2}%");
layer.setDataLabelStyle("Arial Bold", 8, 0x000000).setAlignment(Chart.Bottom);

Hope this can help.

Regards
Peter Kwan