Page 1 of 1

How can I build this chart using high-low chart?

Posted: Wed Jul 17, 2013 8:51 am
by 17064556
Hi!

I'd like to build a how-low chart like the one I've attached below.
I've looked up the guide and samples of TeeChart though, I wasn't able to find the way to do it.
So, for the last hope, I'm posting it on this board.

Key points of the chart I want to builds are as below;
1. Numbers on Y-axis are irregularally growoing.
2. The length of systolic blood pressure range and diastolic blood pressure range are symmetrically the same.
3. If a user inputs parametre values like systolic: 120 and diatolic: 80, is it possilbe to locate the diastolic value below 0? Even though the value itself isn't negative number.

Hope someone's able to answer my question.

Thanks in advance.

Re: How can I build this chart using high-low chart?

Posted: Thu Jul 18, 2013 10:57 am
by yeray
Hi ivic,

TeeChart supports regular and exponential axes, but not irregular. However, you could use the getLabel event in the AxisLabelAdapter to format the labels that are shown, so it can be internally regular but show formatted labels that can be as irregular as you want.

However, having irregular labels in an axis also opens some questions, like: where should a point be exactly drawn if it represents a value that is between two labels? What scale should TeeChart follow to calculate the pixel that corresponds to a value? If the scale in an axis is irregular, the scale between two labels in the axis is also irregular...

Anyway, if you want to have an irregular axis, I assume you know the answers to the doubts above. And I also assume you can find a way to transform your values from an irregular representation to a regular one.

In the following example I use two simple functions to transform the values. The values should be transformed from the irregular scale to the TeeChart regular scale with a function when before adding the values to the series. And the labels should be transformed from the regular scale TeeChart uses to the irregular scale you want to show, using a function inverse of the first.

Code: Select all

	private static void initializeChart() {
		tChart1.getAspect().setView3D(false);
		tChart1.getLegend().setVisible(false);
		
		Candle candle1 = new Candle(tChart1.getChart());
		candle1.setDownCloseColor(Color.blue);
		add(candle1, 120, 80);
		add(candle1, 130, 70);
		add(candle1, 100, 75);
		add(candle1, 115, 65);
		
		tChart1.getAxes().getLeft().setMinMax(-140, 200);
		tChart1.getAxes().getLeft().setMinimumOffset(5);
		tChart1.getAxes().getLeft().setMaximumOffset(5);
		
		tChart1.getAxes().getBottom().setMinMax(0, 20);
		tChart1.getAxes().getBottom().setMinimumOffset(5);
		tChart1.getAxes().getBottom().setMaximumOffset(5);
		
		tChart1.setAxisLabelResolver(new AxisLabelAdapter() {
			
			@Override
			public String getLabel(Axis axis, ISeries s, int valueIndex,
					String labelText) {
				if (axis == tChart1.getAxes().getLeft()) {
					if (valueIndex == -1) {
						double val = Double.parseDouble(labelText.replaceAll(",", "."));
						
						if (val < 0)
							return new DecimalFormat(tChart1.getSeries(0).getValueFormat()).format(transformInv(false, val));
					}
				}
				
				return labelText;
			}
		});
		
		ColorLine col1 = new ColorLine(tChart1.getChart());
		col1.getPen().setColor(Color.red);
		col1.getPen().setStyle(DashStyle.DASH);
		col1.getPen().setWidth(2);
		col1.setAxis(tChart1.getAxes().getLeft());
		col1.setValue(140);
		
		ColorLine col2 = new ColorLine(tChart1.getChart());
		col2.getPen().setColor(Color.red);
		col2.getPen().setStyle(DashStyle.DASH);
		col2.getPen().setWidth(2);
		col2.setAxis(tChart1.getAxes().getLeft());
		col2.setValue(transform(false, 90));
	}
	
	private static void add(Candle series, double systolic, double diastolic) {
		series.add(series.getCount(), transform(true, systolic), transform(true, systolic), transform(false, diastolic), transform(false, diastolic));
	}
	
	private static double transform(boolean isSystolic, double value) {
		if (isSystolic) {
			return value;
		}
		else {
			return value*(-1.25);
		}
	}
	
	private static double transformInv(boolean isSystolic, double value) {
		if (isSystolic) {
			return value;
		}
		else {
			return value/(-1.25);
		}
	}