docs: function (options, redraw, shift, animation) {
              var series = this,
                seriesOptions = series.options,
                data = series.data,
                graph = series.graph,
                area = series.area,
                chart = series.chart,
                names = series.xAxis && series.xAxis.names,
                currentShift = (graph && graph.shift) || 0,
                dataOptions = seriesOptions.data,
                point,
                isInTheMiddle,
                xData = series.xData,
                x,
                i;
  
              setAnimation(animation, chart);
  
              // Make graph animate sideways
              if (shift) {
                  each([graph, area, series.graphNeg, series.areaNeg], function (shape) {
                      if (shape) {
                          shape.shift = currentShift + 1;
                      }
                  });
              }
              if (area) {
                  area.isArea = true; // needed in animation, both with and without shift
              }
  
              // Optional redraw, defaults to true
              redraw = pick(redraw, true);
  
              // Get options and push the point to xData, yData and series.options. In series.generatePoints
              // the Point instance will be created on demand and pushed to the series.data array.
              point = { series: series };
              series.pointClass.prototype.applyOptions.apply(point, [options]);
              x = point.x;
  
              // Get the insertion point
              i = xData.length;
              if (series.requireSorting && x < xData[i - 1]) {
                  isInTheMiddle = true;
                  while (i && xData[i - 1] > x) {
                      i--;
                  }
              }
  
              series.updateParallelArrays(point, 'splice', i, 0, 0); // insert undefined item
              series.updateParallelArrays(point, i); // update it
  
              if (names && point.name) {
                  names[x] = point.name;
              }
              dataOptions.splice(i, 0, options);
  
              if (isInTheMiddle) {
                  series.data.splice(i, 0, null);
                  series.processData();
              }
  
              // Generate points to be added to the legend (#1329)
              if (seriesOptions.legendType === 'point') {
                  series.generatePoints();
              }
  
              // Shift the first point off the parallel arrays
              // todo: consider series.removePoint(i) method
              if (shift) {
                  if (data[0] && data[0].remove) {
                      data[0].remove(false);
                  } else {
                      data.shift();
                      series.updateParallelArrays(point, 'shift');
  
                      dataOptions.shift();
                  }
              }
  
              // redraw
              series.isDirty = true;
              series.isDirtyData = true;
              if (redraw) {
                  series.getAttribs(); // #1937
                  chart.redraw();
              }
          }