Работа с Serial Chart

Коллеги, добрый день!
Возник такой вопрос:

Имеем SerialChart, отображающий столбцы данных по категориям.

По событию onGraphItemClick (клик по столбцу диаграммы) необходимо выделить цветом (или любым других образом) категорию (имя категории или сам стоблец), по которой кликнул пользователь.

Задача - выделение области, примерно, как это делается по событию onSlicePullOut для круговой диаграммы. Нужно показать детализацию информации для выделенного сегмента.

Никак не выходит добраться до нужных свойств… :frowning:

Здравствуйте!

К сожалению, AmCharts не даёт прямого API для выделения DataItem в графиках. Однако можно попробовать реализовать что-то похоже, используя свойство fillColorsField у графика.

Пример с dataContainer.
Используемой сущности добавить MetaProperty поле:

@Transient
@MetaProperty
protected String selected;

Оно будет хранить цвет для выделенного элемента графика. И это поле мы прописываем в выше описанном свойстве fillColorsField:

<charts:graph id="valueGraph"
              type="COLUMN"
              fillColorsField="selected"
              fillAlphas="0.5"
              valueField="value">
</charts:graph>

Далее в контроллере подписываемся на GraphItemClickEvent и в зависимости от значения этого поля будем добавлять или убирать выделение:

@Subscribe("serialChart")
private void onSerialChartGraphItemClick(Chart.GraphItemClickEvent event) {
    EntityDataItem clickedItem = (EntityDataItem) event.getDataItem();
    Task clickedTask = (Task) clickedItem.getItem();

    if (!Strings.isNullOrEmpty(clickedTask.getSelected())) {
        clickedTask.setSelected(null);
    } else {
        List<Task> tasks = tasksDc.getItems();
        for (Task task : tasks) {
            task.setSelected(null);
        }
        clickedTask.setSelected(SELECTED_COLOR);
        showNotification(clickedTask);
    }
    event.getSource().repaint();
}

В итоге получается:
graphclick

Полный пример: demo.zip (84.5 КБ)

4 симпатии

Роман!
Огромнейшее спасибо, за развернутый ответ! Ваша работа - выше всяких похвал.
Это то, что было нужно.

@pinyazhin, остаётся небольшой момент, как не потерять раскраску для случая Stacked диаграммы?
Дело в том, что clickedItem для такой диаграммы, это не сегмент столбика, а весь столбик…
Похоже, надо использовать какое-то другое свойство у графика, или научиться обращаться к сегменту item.

%D0%BD%D0%B0%20%D1%84%D0%BE%D1%80%D1%83%D0%BC%202

Скорее всего придётся иметь свойство выделенного цвета для каждого графика (graph). В слушателе события GraphItemClickEvent нужно проверять какой именно график был нажат (event.getGraphId()) и менять соответствующее свойство.

1 симпатия

Предложенное Романом решение работает отлично (хотя и хотелось бы иметь более удобное API для работы с выделением)!
Однако возникает некоторая сложность с восприятием выделения, если сегментов и цветов на графике много (серый цвет - выделение):
%D1%84%D0%BE%D1%80%D1%83%D0%BC
Вопрос: можно ли динамически использовать какое-то свойство вместо fillColorsField, чтобы, например, изменять цвет рамки или накладывать на item какую-то текстуру, объемность… или еще как-то?

Еще не разобрался, как можно работать с набором цветов, отображаемых на диаграмме (в примере состав блоков и сегментов диаграммы - величина переменная, а цвета предоставляются платформой автоматически).

Подобным способом можно использовать и другие поля для графа:

  • lineColorField - поле для смены цвета границы.
  • alphaField - поле для изменения прозрачности графа. Если базовое значение сделать не высоким, то нажатый элемент будет выделяться среди остальных.

Если известно конечное кол-во графов, то можно использовать элемент colors. Он позволяет указать набор цветов, которые выбираются случайно графиками.

<charts:colors>
    <charts:color value="GREEN"/>
     ...
</charts:colors>

Чтобы лучше понимать значение полей можно смотреть документацию AmCharts. Или JavaDocs клaссов, они повторяют документацию AmCharts.

1 симпатия