AmCharts 4 - несколько наборов данных

пожалуйста, я пытаюсь создать с помощью AmCharts 4 диаграмму с несколькими наборами данных. В предыдущей версии это делается так: https://www.amcharts.com/demos/multiple-data-sets/ но ничего не могу найти как сделать в 4-й версии. Я использую код с их сайта. Все в порядке, следующий график хочу добавить в раздел, начинающийся с комментария добавить ATR -> мне нужно показать его под исходным графиком.

Большое спасибо за любую помощь. Хорошего дня!

var chart = am4core.create("candlestick-chart", am4charts.XYChart);
chart.paddingRight = 20;

// chart.dateFormatter.inputDateFormat = "YYYY-MM-dd";
chart.dateFormatter.inputDateFormat = "x";

var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;

var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;

/*
    add default series
 */

var series = chart.series.push(new am4charts.CandlestickSeries());
series.dataFields.dateX = "date";
series.dataFields.valueY = "close";
series.dataFields.openValueY = "open";
series.dataFields.lowValueY = "low";
series.dataFields.highValueY = "high";
series.dataFields.atr = "atr";
series.dataFields.average_atr = "average_atr";
series.simplifiedProcessing = true;
series.tooltipText = "Open:${openValueY.value}\nLow:${lowValueY.value}\nHigh:${highValueY.value}\nClose:${valueY.value}\nATR:{atr.formatNumber('#.000')}\nAverage ATR:{average_atr.formatNumber('#.000')}";

series.riseFromPreviousState.properties.fillOpacity = 1;
series.dropFromPreviousState.properties.fillOpacity = 0;

chart.cursor = new am4charts.XYCursor();


/*
    add scrollbar
 */
// a separate series for scrollbar
var scrollbarSeries = chart.series.push(new am4charts.LineSeries());
scrollbarSeries.dataFields.dateX = "date";
scrollbarSeries.dataFields.valueY = "close";
// need to set on default state, as initially series is "show"
scrollbarSeries.defaultState.properties.visible = false;

// hide from legend too (in case there is one)
scrollbarSeries.hiddenInLegend = true;
scrollbarSeries.fillOpacity = 0.5;
scrollbarSeries.strokeOpacity = 0.5;

var scrollbarX = new am4charts.XYChartScrollbar();
scrollbarX.series.push(scrollbarSeries);
chart.scrollbarX = scrollbarX;



/*
    add ATR
    -> I need to show it under the original chart
 */
var lineSeriesATR = chart.series.push(new am4charts.LineSeries());
lineSeriesATR.dataFields.dateX = "date";
lineSeriesATR.dataFields.valueY = "atr";
lineSeriesATR.defaultState.properties.visible = false;

// hide from legend too (in case there is one)
lineSeriesATR.hiddenInLegend = true;
lineSeriesATR.fillOpacity = 0.5;
lineSeriesATR.strokeOpacity = 0.5;


chart.data = {!! json_encode($candles) !!};

Я бы рекомендовал использовать chart.js. Это решит вашу проблему

SUNIL JADHAV 27.11.2018 08:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
2 742
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

If you're using Stock Chart, you might want to hold off.

Stock chart is not yet available for V4. We're planning it for the second part of 2018. No exact ETA, yet. Sorry.

https://www.amcharts.com/docs/v4/getting-started/migrating-from-v3/#No_Stock_chart_yet

Ответ принят как подходящий

В AmCharts 4 еще не реализована биржевая диаграмма. Вы можете аппроксимировать панели, синхронизированный курсор и масштабирование, используя контейнеры диаграммы для создания дополнительных диаграмм и используя API, чтобы курсор и полоса прокрутки влияли на все диаграммы.

Вы можете создать каждую диаграмму и поместить их в контейнер диаграммы следующим образом:

var container = am4core.create("chartdiv", am4core.Container); //create the container
container.width = am4core.percent(100); //set dimensions and layout
container.height = am4core.percent(100);
container.layout = "vertical";
// ... for each chart
 var chart = container.createChild(am4charts.XYChart);
// ..set up as usual

При настройке каждой диаграммы вам необходимо настроить события для синхронизации событий масштабирования:

  // whenever any of the charts is zoomed, we should zoom all other charts
  dateAxis.events.on("selectionextremeschanged", function (event) {
    syncDateAxes(event.target);
  })
  // ...

function syncDateAxes(syncWithAxis) {
  for (var i = 0; i < charts.length; i++) {
    var chart = charts[i];
    var dateAxis = chart.xAxes.getIndex(0);
    if (dateAxis != syncWithAxis) {
      dateAxis.events.disableType("selectionextremeschanged");
      dateAxis.start = syncWithAxis.start;
      dateAxis.end = syncWithAxis.end;
      dateAxis.events.enableType("selectionextremeschanged");
    }
  }
}

Вы также захотите настроить курсор каждой диаграммы и синхронизировать каждую из них:

function initCursorListeners() {
  cursorShowDisposers = [];
  for (var i = 0; i < charts.length; i++) {
    var chart = charts[i];
    var cursor = chart.cursor;
    cursor.interactionsEnabled = true;

    cursorShowDisposers.push(cursor.events.on("shown", function (event) {
      handleShowCursor(event.target);
    }));
  }
}

var shownCursorChangeDisposer;
var shownCursorZoomStartedDisposer;
var shownCursorZoomEndedDisposer;

function handleShowCursor(shownCursor) {
  // disable mouse for all other cursors
  for (var i = 0; i < charts.length; i++) {
    var chart = charts[i];
    var cursor = chart.cursor;
    if (cursor != shownCursor) {
      cursor.interactionsEnabled = false;
    }
    // remove show listener
    cursorShowDisposers[i].dispose();
  }

  // add change disposer to the hovered chart cursor
  shownCursorChangeDisposer = shownCursor.lineX.events.on("positionchanged", function (event) {
    syncCursors(shownCursor);
  });


  shownCursorZoomStartedDisposer = shownCursor.events.on("zoomstarted", function (event) {

    for (var i = 0; i < charts.length; i++) {
      var chart = charts[i];
      var cursor = chart.cursor;
      if (cursor != event.target) {
        var point = { x: event.target.point.x, y: 0 };
        cursor.triggerDown(point);
      }
    }
  });

  shownCursorZoomEndedDisposer = shownCursor.events.on("zoomended", function (event) {
    for (var i = 0; i < charts.length; i++) {
      var chart = charts[i];
      var cursor = chart.cursor;
      if (cursor != event.target) {
        var point = { x: event.target.point.x, y: 0 };
        cursor.triggerUp(point);
      }
    }
  });


  shownCursor.events.once("hidden", function (event) {
    shownCursorChangeDisposer.dispose();
    shownCursorZoomStartedDisposer.dispose();
    shownCursorZoomEndedDisposer.dispose();

    for (var i = 0; i < charts.length; i++) {
      var chart = charts[i];
      var cursor = chart.cursor;
      cursor.hide(0);

      cursorShowDisposers[i].dispose();
    }

    initCursorListeners();
  });
}

function syncCursors(syncWithCursor) {
  for (var i = 0; i < charts.length; i++) {
    var chart = charts[i];
    var cursor = chart.cursor;

    var point = { x: syncWithCursor.point.x, y: 0 };

    if (cursor != syncWithCursor) {
      cursor.triggerMove(point);
    }
  }
}

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

Вот полная демонстрация о том, как все это делать. Это также включено в папку примеров в zip-файле AmCharts.

Спасибо большое за помощь! Хорошего дня

Jan Kožušník 21.11.2018 20:19

В чем разница между использованием контейнеров и серий в одной диаграмме? Контейнеры лучше производят? Потому что производительность серий ужасна, когда у меня есть несколько диаграмм на одной странице с множеством точек данных в каждой серии.

Yasir Jan 13.07.2019 16:03

По производительности разницы нет. Вы смотрели советы по производительности на amcharts.com/docs/v4/concepts/performance? Если это не помогает и вы используете данные на основе дат, подумайте об использовании фондовых диаграмм версии 3 на время, пока диаграмма акций версии 4 не будет готова.

xorspark 15.07.2019 05:27

@xorspark, если бы вы изменили / реорганизовали это с помощью последней версии Amcharts 4, что бы вы изменили?

Chukwuma Nwaugha 15.07.2020 06:17

@xorspark Мне нужно синхронизировать несколько диаграмм с помощью (1. движения курсора (2. эффектов масштабирования (3. одиночной полосы прокрутки XYChartScrollbar на оси даты). Пожалуйста, мне не удалось заставить вашу демонстрацию работать на 100%, чтобы удовлетворить эти потребности.

Chukwuma Nwaugha 15.07.2020 06:21

@ChukwumaNwaugha - Пара вещей. 1) Демо работает в последней версии AmCharts 4, как вы можете видеть в коде. Никакого рефакторинга не требуется, поэтому ваш первый вопрос даже не актуален. 2) Использование ответа на вопрос двухлетней давности для другого запроса противоречит правилам SO. Задайте новый вопрос, и кто-нибудь ответит.

xorspark 16.07.2020 01:12

Это отличный пример. Я рекомендую прямо посмотреть демо по ссылке

John 16.04.2021 19:07

Другие вопросы по теме