|
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 |
|
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
|
Re: x Axis labels as legend |
Posted by Peter Kwan on Aug-22-2012 19:14 |
|
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 |
|
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.
|
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 |
|