Есть некоторые проблемы с тем, как вы сейчас используете форматтер. С одной стороны, вы не можете иметь два return
в одной функции без каких-либо предложений if. Это будет означать, что будет использоваться только первый return
.
В любом случае, вот некоторые улучшения, которые я предлагаю вам сделать для своего кода.
Добавьте дополнительную информацию для каждой точки к старшим диаграммам, что значительно упрощает доступ к этой информации через старшие диаграммы. Например. во всплывающей подсказке. Вы можете установить данные следующим образом:
chartData1.map(function(row) {
return {
x: row.timestamp,
y: row.value,
somethingElse: row.somethingElse
}
})
Если вы сделаете это, то возвращение правильной всплывающей подсказки для каждой серии будет простым делом:
tooltip: {
formatter () {
// this.point.x is the timestamp in my original chartData array
return this.point.somethingElse
}
}
Пример работающего JSFiddle: https://jsfiddle.net/ewolden/dq7L64jg/6/
Если вы хотите получить больше информации в подсказке, вы можете сделать:
[ 112]
Кроме того, вам нужно убедиться, что элементы xAxis, т.е. ваши временные метки, отсортированы. Это требование для высоких графиков для правильной работы. На самом деле, ваш пример сообщает
Ошибка Highcharts # 15: www.highcharts.com/errors/15
blockquote>в консоли, потому что chartData2 находится в обратном порядке , В этом примере все выглядит хорошо, но более сложные примеры могут привести к тому, что диаграмма будет выглядеть не так, как вы ожидаете.
Для этого примера использование обратного достаточно просто:
data: chartData2.
reverse()
.map(function(row) {return {x: row.timestamp, y: row.value, somethingElse: row.somethingElse}})
Рабочий пример JSFiddle: https: // jsfiddle.net/ewolden/dq7L64jg/7/
Необходимо использовать new
когда Вы желаете объекту остаться существующими до Вас delete
это. Если Вы не используете new
затем объект будет уничтожен, когда он выйдет из объема. Некоторые примеры этого:
void foo()
{
Point p = Point(0,0);
} // p is now destroyed.
for (...)
{
Point p = Point(0,0);
} // p is destroyed after each loop
Некоторые люди скажут что использование new
решает, является ли Ваш объект на "куче" или стеке, но это только верно для переменных, объявленных в функциях.
В примере ниже местоположения 'p' будет то, где его содержание объекта, Foo, выделяется. Я предпочитаю называть это 'оперативное' выделение.
class Foo
{
Point p;
}; // p will be automatically destroyed when foo is.
Выделение (и освобождение) возражают с использованием new
является намного более дорогим, чем если бы они выделяются оперативные, таким образом, его использование должно быть ограничено туда, где необходимо.
Второй пример того, когда выделить через new
для массивов. Вы не можете* изменять размер оперативного массива или массива стека во времени выполнения поэтому, где Вам нужен массив неопределенного размера, это должно быть выделено через новый.
Например.
void foo(int size)
{
Point* pointArray = new Point[size];
...
delete [] pointArray;
}
(*pre-emptive придирающийся к мелочам - да, существуют расширения, которые позволяют переменной измеренные выделения стека).
Необходимо использовать новый, когда Вы хотите, чтобы объект был создан на "куче" вместо стека. Это позволяет объекту быть полученным доступ снаружи текущей функции или процедуры через помощь указателей.
Это могло бы быть полезно для Вас для поиска указателей и управления памятью в C++, так как это вещи, с которыми Вы вряд ли столкнетесь на других языках.
Смотрите на этот вопрос и этот вопрос для некоторых хороших ответов на инстанцировании объекта C++.
Эта основная идея состоит в том, что объекты, которые инстанцируют на "куче" (использующий новый), должны быть очищены вручную, те, которые инстанцируют на стеке (без нового) автоматически очищены, когда они выходят из объема.
void SomeFunc()
{
Point p1 = Point(0,0);
} // p1 is automatically freed
void SomeFunc2()
{
Point *p1 = new Point(0,0);
delete p1; // p1 is leaked unless it gets deleted
}
Новый всегда используется для выделения динамической памяти, которая затем должна быть освобождена.
Путем выполнения первой опции будет автоволшебно освобождена та память, когда объем будет потерян.
Point p1 = Point(0,0); //This is if you want to be safe and don't want to keep the memory outside this function.
Point* p2 = new Point(0, 0); //This must be freed manually. with...
delete p2;