Диаграммы на Android - проблемы с androidplot и achartengine
Я хочу интегрировать простой график XY в моей деятельности. В поисках бесплатных графиков с настройкой (настраиваемые фоны, цвета, метки осей) я нашел двух кандидатов: Achartengine и Adnroidplot. Были некоторые другие библиотеки, но они не были настраиваемыми или доступными только как отдельные Intents.
Мне также нужна поддержка более старого Android API (должна быть поддержана как минимум 1.6).
Я попробовал Achartengine, но это не удалось, когда я интегрировал его в ScrollView. Когда я прокручивал, диаграмма как-то повредилась, сжалась, и некоторые элементы фона, казалось, исчезли.
Тогда я попробовал Adnroidplot. Сначала он не запустился на 1.6 из-за класса Pair. Но я нашел решение проблемы на форуме Adnroidplot. Казалось, что все работает нормально, также динамические обновления, хотя пользовательские Обозреватели работали нормально. Было немного сложно настроить метки оси X (мне нужны были пользовательские строки там, а не числа), но с помощью специального форматера я, наконец, сделал это.
Но потом я попробовал это с реальными данными из базы данных клиента. Было несколько серий точек с одинаковыми значениями. И я был шокирован, увидев, что Adnroidplot не умеет рисовать горизонтальную линию, он зависает или полностью портит график!
Вот тестовый пример, я позаимствовал его у Adnroidplot Quickstart и сделал небольшую модификацию, чтобы сделать одну серию с равными значениями:
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// Create array of y-values to plot:
Number[] series1Numbers = {7, 7}; // horizontal line expected, got nothing or hang
// Turn the above arrays into XYSeries:
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
"Series1"); // Set the display title of the series
// Create a formatter to use for drawing a series using LineAndPointRenderer:
LineAndPointFormatter series1Format = new LineAndPointFormatter(
Color.rgb(0, 200, 0), // line color
Color.rgb(0, 100, 0), // point color
null); // fill color (optional) <- my app hangs if I add it for a horizontal line
// Add series1 to the xyplot:
pricesPlot.addSeries(series1, series1Format);
// Reduce the number of range labels
pricesPlot.setTicksPerRangeLabel(3);
// By default, AndroidPlot displays developer guides to aid in laying out your plot.
// To get rid of them call disableAllMarkup():
pricesPlot.disableAllMarkup();
Я уже писал на форумах Adnroidplot, но я не уверен, насколько быстро они ответят и когда проблема будет решена.
Поэтому я надеюсь, что кто-то в Stackru может найти обходной путь для этого?
3 ответа
Спасибо разработчикам на форумах Androidplot, теперь я получил решение. Следующий код является фрагментом моего файла Activity.java. К сожалению, окончательный код был позже подвергнут рефакторингу, и некоторые части были перемещены в пользовательский источник данных и пользовательские XYSeries, которые я не имею разрешения публиковать здесь.
Этот код работал для Androidplot-core-0.4.4-release.jar, и я не уверен, будет ли он работать с более поздними версиями.
// for chart
private XYPlot pricesPlot;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other initialisation code omitted for brevity ...
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// the following code was added as a debug code to test that it works.
// later many things were changed, so take it "as is" - this was the core of the solution
PriceDatesFormat ppf = new PriceDatesFormat();
ppf.Labels = new String[]{
"2011-01",
"2011-05",
"2011-07",
"2011-11",
"2011-07",
"2011-07"
};
pricesPlot.getGraphWidget().setDomainValueFormat(ppf);
// Create two arrays of y-values to plot:
Float [] seriesNumbers = new Float[]{118f, 185f};
Float min = Collections.min(Arrays.asList(seriesNumbers));
Float max = Collections.max(Arrays.asList(seriesNumbers));
pricesPlot.setRangeBoundaries(min - 0.1*min, max + 0.1*max, BoundaryMode.AUTO);// make them a bit wider out of min/max values
Я придумал легкий обходной путь, чтобы убедиться, что горизонтальные линии показаны.
По сути, просто нарисуйте 3-точечную серию Y_VALS_ONLY, прежде чем загружать свой первый реальный график.
Предполагая, что у вас есть файл colors.xml res, вы можете создать чистую серию, подобную этой:
Объявите это:
Number[] yClear = {0, 1, 0};
LineAndPointFormatter clearFormat;
SimpleXYSeries clear= null;
В вашем onCreate() или onViewCreated():
clearFormat = new LineAndPointFormatter(getResources().getColor(R.color.transparent), getResources().getColor(R.color.transparent), 0, null);
Затем, после того, как вы настроите свой график, просто добавьте чистый график на график;
clear = new SimpleXYSeries( Arrays.asList(yClear), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Clear");
yourPlot.addSeries(clear, clearFormat);
Я часами пытался отладить эту проблему, и все сводилось к тому, чтобы упростить жизнь и сделать это таким образом.
Для тех, кто погуглил проблемы сжатия диаграммы в ScrollView с помощью AChartEngine, это решение вашей проблемы:
renderer.setInScroll(true);