Статьи

Визуализируйте большие наборы данных на основе даты и времени с AnyStock

Я представил основы семейства продуктов AnyChart в моей предыдущей статье на SitePoint . На этот раз я расскажу вам о том, как AnyStock помогает визуализировать данные о запасах, а также о любых больших наборах данных на основе даты и времени (и как лучше их использовать).

AnyStock является частью JavaScript-библиотеки AnyChart, которая продается как набор продуктов:

  • AnyChart — распространенные типы графиков,
  • AnyMap — географические карты и карты мест,
  • AnyGantt — Project Gantt , Resource и PERT,
  • AnyStock — визуализация больших наборов данных на основе даты / времени, особенности которых являются темой данной статьи.

Поскольку AnyChart — это, по сути, одна большая библиотека JavaScript-диаграмм, API является общим, и все диаграммы настраиваются примерно одинаково, разделяя темы , настройки и способы загрузки данных . Тем не менее, большинство вещей и подходов, которые вы узнаете в этой статье, могут быть легко применены для создания других диаграмм и карт.

Смотреть визуализировать данные с D3.js
Проиллюстрируйте свои данные с помощью JavaScript

Графики акций AnyStock представляют собой особый тип графиков, которые могут эффективно визуализировать большие объемы данных на основе даты / времени . Он имеет множество специальных функций, таких как масштабирование с пользовательским интерфейсом Scroller, синхронизированные графики, группирование данных и так далее. AnyStock полностью совместим со всеми другими графиками AnyChart, и помимо наличия всех основных функций акций, таких как группировка, потоковая передача, прокрутка и т. Д. , Акции AnyStock также имеют несколько встроенных технических индикаторов и возможность их настройки .

Короче говоря, в этой статье я буду:

AnyStock Быстрый старт

Чтобы начать использовать AnyStock на своей HTML-странице, вам понадобятся три простых вещи. Первый — это ссылка на файл библиотеки JavaScript. Второй — это элемент HTML уровня блока; Вот пример HTML-шаблона, который вы можете использовать:

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <script src="https://cdn.anychart.com/js/7.14.3/anystock.min.js"></script>    
    <style>
    html, body, #container {
      width: 100%;
      height: 100%;
    }
  </style>    
    <title>AnyStock Basic Example</title>    
  </head>
  <body>
    <div id="container"></div>
    <script>
      // AnyStock code here
    </script>
  </body>
</html>

А вот основной код для создания простой японской диаграммы свечей , а также объем на втором графике и скроллер, который отображает объем в виде области:

 anychart.onDocumentReady(function() {
    // data
    var data = [
      ['2015-12-24', 511.53, 514.98, 505.79, 506.40, 1050016],
      ['2015-12-25', 512.53, 514.88, 505.69, 505.34, 1050015],
      ['2015-12-26', 511.83, 514.98, 505.59, 506.23, 1050016],
      ['2015-12-27', 511.22, 515.30, 505.49, 506.47, 1250016],
      ['2015-12-28', 510.35, 515.72, 505.23, 505.80, 1250015],
      ['2015-12-29', 510.53, 515.86, 505.38, 508.25, 1250018],
      ['2015-12-30', 511.43, 515.98, 505.66, 507.45, 1250017],
      ['2015-12-31', 511.50, 515.33, 505.99, 507.98, 1250017],
      ['2016-01-01', 511.32, 514.29, 505.99, 506.37, 1250016],
      ['2016-01-02', 511.70, 514.87, 506.18, 506.75, 1250016],
      ['2016-01-03', 512.30, 514.78, 505.87, 508.67, 1250018],
      ['2016-01-04', 512.50, 514.77, 505.83, 508.35, 1250018],
      ['2016-01-05', 511.53, 516.18, 505.91, 509.42, 1050019],
      ['2016-01-06', 511.13, 516.01, 506.00, 509.26, 1050019],
      ['2016-01-07', 510.93, 516.07, 506.00, 510.99, 1050110],
      ['2016-01-08', 510.88, 515.93, 505.22, 509.95, 1350019],
      ['2016-01-09', 509.12, 515.97, 505.15, 510.12, 1350110],
      ['2016-01-10', 508.53, 516.13, 505.66, 510.42, 1350110],
      ['2016-01-11', 508.90, 516.24, 505.73, 510.40, 1350110]
    ];

    // create stock chart
    chart = anychart.stock();
    chart.title("AnyStock: Basic Sample");

    // create data table and load data in it
    table = anychart.data.table();
    table.addData(data); 

    // map data - name fields
    mapping = table.mapAs({open: 1, high: 2, low: 3, close: 4, value: 5});

    // create series to show stock changes
    chart.plot(0).candlestick(mapping).name("Stock name");
    // create second plot and show trading volume there as a line
    chart.plot(1).column(mapping).name("Volume");
    // create series to show trading volume
    chart.scroller().area(mapping);

    // set HTML container and draw chart into it
    chart.container('container').draw();     
});

Отображение данных

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

Что такое отображение данных? Давайте немного углубимся в это, так как мы уже хорошо использовали эту функцию в базовом образце AnyStock и будем продолжать использовать ее в каждом образце в этой статье.

Как говорится в этой статье в Википедии о сопоставлении данных

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

Один из способов перевести это определение в термины непрофессионала: «Отображение данных — это правило, которое сообщает, что есть в данных, и подготавливает некоторые данные для использования в другом месте».

Я знаю, что это может звучать грубо и упрощенно, но все же может быть полезно.

Теперь давайте посмотрим, как происходит сопоставление данных в приведенном выше примере. Во-первых, у нас есть массив с числами и датами, которые мы загружаем в таблицу:

 // data
var data = [
  ['2015-12-24', 511.53, 514.98, 505.79, 506.40, 1050016],
  ['2015-12-25', 512.53, 514.88, 505.69, 505.34, 1050015],
  ['2015-12-26', 511.83, 514.98, 505.59, 506.23, 1050016],
  ['2015-12-27', 511.22, 515.30, 505.49, 506.47, 1250016],
  ['2015-12-28', 510.35, 515.72, 505.23, 505.80, 1250015],
  ['2015-12-29', 510.53, 515.86, 505.38, 508.25, 1250018],
  ['2015-12-30', 511.43, 515.98, 505.66, 507.45, 1250017],
  ['2015-12-31', 511.50, 515.33, 505.99, 507.98, 1250017]
];

// create data table and load data in it
table = anychart.data.table();
table.addData(data); 

В этих данных нет ничего, что объясняло бы, какие столбцы содержат цены или что-либо еще. Цены открытия, максимума, минимума и закрытия могут быть в любом порядке. Так как же библиотека AnyStock понять, что к чему? Используя сопоставления данных!

В этом случае нам нужен только один:

 // map data - name fields
mapping = table.mapAs({open: 1, high: 2, low: 3, close: 4, value: 5});

Как мы видим, метод mapAs()

 // create series to show stock changes
chart.plot(0).candlestick(mapping).name("Stock name");
// create second plot and show trading volume there as line
chart.plot(1).column(mapping).name("Volume");
// create series to show trading volume
chart.scroller().area(mapping);

AnyStock ожидает отображение с полями openhighlowcloseсерии свечей и valueобласти и столбца, и это позволяет нам использовать одно отображение в этом случае.

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

Предположим, данные поступают так:

 var data = [
  {'date': '2015-12-24', 'o': 511.53, 'h': 514.98, 'l': 505.79, 'c': 506.40, 'vol': 1050016},
  {'date': '2015-12-25', 'o': 512.53, 'h': 514.88, 'l': 505.69, 'c': 505.34, 'vol': 1050015},
  {'date': '2015-12-26', 'o': 511.83, 'h': 514.98, 'l': 505.59, 'c': 506.23, 'vol': 1050016},
  {'date': '2015-12-27', 'o': 511.22, 'h': 515.30, 'l': 505.49, 'c': 506.47, 'vol': 1250016},
  {'date': '2015-12-28', 'o': 510.35, 'h': 515.72, 'l': 505.23, 'c': 505.80, 'vol': 1250015},
  {'date': '2015-12-29', 'o': 510.53, 'h': 515.86, 'l': 505.38, 'c': 508.25, 'vol': 1250018},
  {'date': '2015-12-30', 'o': 511.43, 'h': 515.98, 'l': 505.66, 'c': 507.45, 'vol': 1250017},
  {'date': '2015-12-31', 'o': 511.50, 'h': 515.33, 'l': 505.99, 'c': 507.98, 'vol': 1250017},
  {'date': '2016-01-01', 'o': 511.32, 'h': 514.29, 'l': 505.99, 'c': 506.37, 'vol': 1250016},
  {'date': '2016-01-02', 'o': 511.70, 'h': 514.87, 'l': 506.18, 'c': 506.75, 'vol': 1250016}];

Во многих других решениях вам придется создавать сценарий, который изменяет структуру данных, переименовывает поля, просматривает один набор данных и формирует новый. Это не относится к AnyChart.

Сначала мы загружаем данные в таблицу и сообщаем ей, где находится аргумент (отметка времени):

 // create data table and load data in it
table = anychart.data.table('date');
table.addData(data); 

Затем мы создаем отображения и, в этом случае, создадим четыре из них. Три отображения рассматривают некоторые поля как valuehighlow

 // map data
mapping_1 = table.mapAs({value: 'o'});
mapping_2 = table.mapAs({value: 'c'});
mapping_3 = table.mapAs({high: 'h', low: 'l'});
mapping_4 = table.mapAs({value: 'vol'});

Теперь мы готовы передать эти отображения четырем конструкторам серии:

 // create a series to show open prices line
chart.plot(0).line(mapping_1).name("Open");
// create a series to show close prices line
chart.plot(0).line(mapping_2).name("Close");      
// create a second plot and show trading volume there as a line
chart.plot(0).rangeSplineArea(mapping_3).name("Range");
// create a series in a scroller
chart.scroller().stick(mapping_4);

… И наслаждайтесь нашим образцом AnyStock Advanced Mappings на CodePen :

Аккуратно, верно? Отображение данных — это гибкий инструмент, который экономит много усилий при интеграции сторонних источников, что я продемонстрирую в примерах Google Finance и Xignite API ниже.

Загрузка файла CSV

Перед просмотром следующего примера вы должны понять, как загружать файлы CSV с AnyChart. На самом деле вы можете сделать это, используя jQuery или любую другую библиотеку AJAX по вашему выбору, но AnyChart имеет свой собственный вспомогательный скрипт: AnyChart Data Adapter . Это позволяет легко загружать файлы CSV, JSON и XML, а также загружать данные из таблиц HTML в AnyChart .

Чтобы узнать больше, прочитайте раздел « Начало работы с AnyChart: загрузка файлов CSV » из моей предыдущей статьи.

Google Finance

Отказ от ответственности: Google Finance предоставляет данные без каких-либо обязательств, а AnyChart не имеет никакого отношения к Google. Этот образец создан, чтобы показать, как данные могут быть получены только из сторонних источников, а не как рекомендация полагаться на Google Finance в качестве единственного (или лучшего) источника цен на акции.

Чтобы загрузить данные CSV из Google Finance, вам необходимо знать:

С учетом всего этого всего лишь 10 строк кода загружают ваш график и показывают данные о запасах:

 // stock symbol to load
ticker = "MSFT";
anychart.onDocumentReady(function() {
    // create chart
    chart = anychart.stock();
    chart.title("AnyStock: Data from Google Finance");
    // set HTML container and draw chart into it
    chart.container('container').draw(); 

    // load CSV from Google Finance, we use https://crossorigin.me/ to avoid cross origin problems
    // they still might occur, just reload sample to see appropriate result
    anychart.data.loadCsvFile("https://crossorigin.me/https://www.google.com/finance/historical?output=csv&q=" + ticker, function (data) {
      // create data table structure
      table = anychart.data.table();
      // load data received
      table.addData(data); 
      // map data
      mapping = table.mapAs({open: 1, high: 2, low: 3, close: 4, value: 5});
      // create series to show chart prices
      chart.plot(0).ohlc(mapping).name(ticker);
      // create series to show trading volume in scroller
      chart.scroller().column(mapping).name("Volume");
    });
});

Вот пример CodePen, демонстрирующий загрузку данных из Google Finance в AnyStock . Я добавил элемент Preloader, который входит в пакет диаграмм AnyChart, но вы можете использовать любой другой, если хотите:

Xignite API

Ниже мы видим еще один пример того, как сопоставление данных упрощает вещи.

Xignite, Inc. предоставляет облачные API данных финансового рынка, чтобы помочь компаниям предоставлять в реальном времени и справочные рыночные данные. Клиентами Xignite являются такие компании, как Betterment, FutureAdvisor, Motif Investing, Личный капитал, Robinhood, StockTwits, Wealthfront и Yodlee.

У Xignite есть множество API , но мы создадим образец с названием «GetGlobalHistoricalQuotesAsOf» . Он возвращает диапазон исторических котировок для ценной бумаги на основе конечной даты и количества периодов.

Мы взяли примерный набор, типичный для того, что может вернуть этот API. Вот как это выглядит (для ясности показаны только две точки, образец содержит больше):

 {
    "Security": {
        "CIK": "0001446250",
        "Cusip": "D12096109",
        "Symbol": "BMW.XETR",
        "ISIN": "DE0005190003",
        "Valoren": "324410",
        "Name": "BMW",
        "Market": "XETRA",
        "CategoryOrIndustry": "Invalid",
        "Outcome": "Success",
        "Message": null,
        "Identity": null,
        "Delay": 0
    },
    "StartDate": "10/4/2016",
    "EndDate": "4/2/2017",
    "GlobalQuotes": [
        {
            "Security": null,
            "Date": "10/4/2016",
            "Last": 77.29,
            "Open": 76,
            "High": 77.68,
            "Low": 75.79,
            "Volume": 2802839,
            "LastClose": 74.81,
            "ChangeFromOpen": 1.29,
            "PercentChangeFromOpen": 1.697,
            "ChangeFromLastClose": 2.48,
            "PercentChangeFromLastClose": 3.315,
            "SplitRatio": 1,
            "CummulativeCashDividend": 0,
            "CummulativeStockDividendRatio": 1,
            "Currency": "EUR",
            "AdjustmentMethodUsed": "SplitAndProportionalCashDividend",
            "DataConfidence": "Valid",
            "Outcome": "Success",
            "Message": null,
            "Identity": null,
            "Delay": 0
        },
        {
            "Security": null,
            "Date": "10/5/2016",
            "Last": 78.18,
            "Open": 76.65,
            "High": 78.39,
            "Low": 75.98,
            "Volume": 1831075,
            "LastClose": 77.29,
            "ChangeFromOpen": 1.53,
            "PercentChangeFromOpen": 1.996,
            "ChangeFromLastClose": 0.89,
            "PercentChangeFromLastClose": 1.152,
            "SplitRatio": 1,
            "CummulativeCashDividend": 0,
            "CummulativeStockDividendRatio": 1,
            "Currency": "EUR",
            "AdjustmentMethodUsed": "SplitAndProportionalCashDividend",
            "DataConfidence": "Valid",
            "Outcome": "Success",
            "Message": null,
            "Identity": null,
            "Delay": 0
        }
    ],
    "Outcome": "Success",
    "Message": null,
    "Identity": "Request",
    "Delay": 0.21875
}

Работа с этим сложным JSON в AnyStock настолько проста, что я решил поиграть и продемонстрировать некоторые другие функции этой библиотеки, такие как возможность показывать разные данные на одном графике, несколько масштабов, а также форматирование осей и меток:

 anychart.onDocumentReady(function() {
      // create chart and set title
      chart = anychart.stock();    
      chart.title("AnyStock: Data from Xignite API JSON");

      // load data from Xignite
      // see function in sample on Codepen https://codepen.io/anystock/pen/gmqvdy
      data = loadDataFromXignite();
      // get ticker ID from JSON object
      ticker = data.Security.Symbol;
      // create table and specify argument field 
      table = anychart.data.table("Date");
      // load data into table
      table.addData(data.GlobalQuotes); 

      // map data for OHLC
      ohlc_mapping = table.mapAs({ "high": "High", "low": "Low", "open": "Open", "close": "LastClose"});

      // map data for volume
      volume_mapping = table.mapAs({ "value": "Volume"});

      // create series to show chart prices
      price = chart.plot(0).ohlc(ohlc_mapping).name(ticker);

      // Create and tune additional Y scale
      // to show volume on the same plot as prices
      var extraYScale = anychart.scales.linear();
      // make volume always appear in lower 1/8th part of plot
      extraYScale.maximumGap(8);
      // Create and tune additional Y axis
      var extraYAxis = chart.plot(0).yAxis(1);
      extraYAxis.orientation("right");
      extraYAxis.labels().format("{%Value}{scale:(1000000)|(Mln)}");
      extraYAxis.scale(extraYScale); 
      // give space to labels to the right
      chart.padding().right(50);

      // create series to show trading volume        
      volume = chart.plot(0).column(volume_mapping).name("Volume"); 
      // bind it to extra scale
      volume.yScale(extraYScale);

      // set HTML container and draw chart into it
      chart.container('container').draw();   
  });

Этот пример на CodePen показывает, как AnyStock использует данные из API Xignite GetGlobalHistoricalQuotesAsOf :

Вывод

В этой статье я познакомил вас с модулем AnyStock всеобъемлющей библиотеки JavaScript-графиков AnyChart (или библиотекой AnyStock для фондовых и больших интерактивных диаграмм на основе даты и времени по мере их продажи). Я показал, как вы можете легко интегрировать сторонние данные в финансовые диаграммы, что очень важно, потому что данные являются ключевым элементом, когда речь заходит о финансах.

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

Последние две упомянутые функции (пользовательские индикаторы и пользовательские ряды) особенно аккуратны, но работа с ними требует некоторого понимания математики и обработки данных. Сначала я рассматривал возможность добавления примеров этих функций в этой статье, но затем отказался от этой идеи: AnyChart (включая AnyStock) — это простой инструмент для использования в большинстве случаев, и он имеет мощные точки расширения. Но ~~ с большой силой приходит большая ответственность ~~, когда речь идет о продвинутых темах, требуется расширенное кодирование и опыт, в то время как я не хочу пугать вас большим количеством информации и текста в той же статье.

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

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