Builds the pie layout that will produce data ready to draw
@private
967767
function buildLayout() {
            layout = d3Shape.pie()
                .padAngle(paddingAngle)
                .value(getQuantity)
                .sort(orderingFunction);
        }
1146981
function buildChart() {
      var self = this;

      // If dataTable isn't set, build it
      var dataTable = _.isEmpty(self.dataTable) ? self.buildDataTable() : self.dataTable;

      self.wrapper = self.buildWrapper(self.chartType, dataTable, self.options, self.chartId);

      // Set the datatable on this instance
      self.dataTable = self.wrapper.getDataTable();

      // After chart is built, set it on this instance and resolve the promise.
      google.visualization.events.addOneTimeListener(self.wrapper, 'ready', function () {
        self.chart = self.wrapper.getChart();
        chartDeferred.resolve();
      });
    }
50991
function p() {

    // global promise object to wait for all plot options to be completed before writing
    this.promises = [];
    // global array for options to plot
    this.optArray = [];

    // simple plot
    this.plot = function(seriesArr, title, yLabel, xLabel) {
        // console.log("plotting")
        var defer = q.defer();
        this.promises.push(defer.promise);

        title = title || false;
        yLabel = yLabel || false;
        xLabel = xLabel || false;

        var opt = _.cloneDeep(tmpOpt),
        set = _.set.bind(null, opt);

        set('series', seriesArr);
        set('title.text', title);
        set('yAxis.title.text', yLabel);
        set('xAxis.title.text', xLabel);

        // setTimeout(function() {}, 2000);
        this.optArray.push(opt);
        defer.resolve();
        return opt;
    };

    // advance plot = specify your own highcharts options
    this.advPlot = function(opt) {
        var defer = q.defer();
        this.promises.push(defer.promise);
        this.optArray.push(opt);
        defer.resolve();

        return opt;
    };

    // write highchart options to json for rendering
    // if autosave is true, charts will save on view
    this.write = function(autosave) {
        var defer = q.defer();
        for (var i = 0; i < this.optArray.length; i++) {
            _.set(this.optArray[i], 'chart.renderTo', 'hchart' + i);
            _.set(this.optArray[i], 'autosave', autosave);
        }
        fs.writeFile(__dirname + '/src/options.json', JSON.stringify(this.optArray), defer.resolve);

        return defer.promise;
    };

    // serialize optArray and write to
    this.serialize = function(autosave) {
        var defer = q.defer();

        q.all(this.promises)
        .then(this.write(autosave))
        .then(defer.resolve());

        return defer.promise;
    };

    // finally, render after all plots specified
    // if autosave is true, charts will save on view
    this.render = function(autosave) {
        var gulpplot = require(__dirname + '/../gulpfile.js').gulpplot;
        
        this.serialize(autosave)
        .then(gulpplot)
    };

    this.dynrender = function() {
        this.serialize()
        // .then(dyngulpplot)
    };
}
722179
function (cb, data, layout) {
            var self = this;

            Y.prepare([DEFAULT_THEME, themeDir], self.getProjectMeta(), function (err, opts) {
                if (err) {
                    console.log(err);
                }
                if (!data.name) {
                    return;
                }

                opts.meta = Y.merge(opts.meta, data);

                opts.meta.title = self.data.project.name;
                opts.meta.moduleName = data.name;
                opts.meta.projectRoot = '../';
                opts.meta.projectAssets = '../assets';
                opts.meta.projectLogo = self._resolveUrl(self.data.project.logo, opts);

                opts = self.populateClasses(opts);
                opts = self.populateModules(opts);
                opts = self.populateFiles(opts);

                opts.meta.fileName = data.name;
                fs.readFile(opts.meta.fileName, Y.charset, Y.rbind(function (err, str, opts, data) {
                    if (err) {
                        Y.log(err, 'error', 'builder');
                        cb(err);
                        return;
                    }

                    if (typeof self.options.tabspace === 'string') {
                        str = str.replace(/\t/g, self.options.tabspace);
                    }

                    opts.meta.fileData = str;
                    var view = new Y.DocView(opts.meta, 'index');
                    var mainLayout = opts.layouts[layout];
                    self.render('{{>files}}', view, mainLayout, opts.partials, function (err, html) {
                        self.files++;
                        cb(html, view, data);
                    });

                }, this, opts, data));
            });

        }
944090
function render(){

	ll('Render start...');

	ll('nodes: ' + bbop.dump(nodes));
	// ll('matrix: ' + dump(matrix));
	ll('val_hash: ' + bbop.dump(val_hash));
	ll('max_val: ' + bbop.dump(max_val));

	var haxis = f2;
	var hhead = global_facet2;
	var vaxis = f1;
	var vhead = global_facet1;
	// Figure out which axis is the longer one and switch.
	// if( vaxis.length > haxis.length ){
	//     haxis = f1;
	//     vaxis = f2;	    
	//     vhead = global_facet1;
	//     hhead = global_facet2;
	// }

	var td_id_to_data = {};
	function _assemble_table(haxis, vaxis){
	    ll('try to _assemble_table...');
	    
	    // Start assembling the table parts.	
	    var thead = new html.tag('thead');
	    
	    // Add what we want in the header row.
	    var head = '';
	    var title_list = [head];
	    us.each(haxis, function(hline){
		var ht = hline[0];
		title_list.push(ht);
	    });
	    // Push the header row into thead.
	    us.each(title_list, function(title_item){
		thead.add_to('<th>' + title_item +
			     '<img style="border: 0px;" src="' +
			     sd.image_base + '/reorder.gif" />' +
			     '</th>');
	    });
	    
	    var tbody = new html.tag('tbody');
	    
	    // Add the rows.
	    us.each(vaxis, function(vline){
		var vt = vline[0];
		
		// Header row.
		var rhead = '<td style="background-color:#e9effa"><b>' +
			vt + '</b></td>';
		var row = [rhead];
		
		// Data rows.
		us.each(haxis, function(hline){
		    var ht = hline[0];
		    var cell_val = val_hash[vt][ht];
		    
		    var color = value_to_color(cell_val);
		    
		    // Data entry.
		    var td_attrs = {
			style: 'background-color:' +color + ';',
			title: vt +', '+ ht +': '+ cell_val,
			'class': 'bbop-js-tooltip',
			generate_id: true
		    };
		    var td = new html.tag('td', td_attrs, cell_val);
		    row.push(td.to_string());
		    
		    // Now save the data for later callback
		    // generation.
		    td_id_to_data[td.get_id()] = {
			x: ht,
			y: vt,
			z: cell_val
		    };
		});
		
		tbody.add_to('<tr>' + row.join('') + '</tr>');
	    });

	    //var tbl = new html.table(title_list);
	    var table_attrs = {
		'generate_id': true,
		'class': 'table' // bs3
	    };
	    var table = new html.tag('table', table_attrs);
	    table.add_to(thead);
	    table.add_to(tbody);

	    return table;
	}

	// Add table and sorting to DOM.
	jQuery(results_head).append(vhead + ' &#92; ' + hhead);
	var table_a = _assemble_table(haxis, vaxis);
	jQuery(results_div).append(table_a.to_string());
	jQuery('#' + table_a.get_id()).tablesorter();

	// Add tooltips.
	//var tt_args = {'position': {'my': 'left bottom', 'at': 'right top'}};
	var tt_args = {
	    'position': {'my': 'center bottom-5', 'at': 'center top'},
	    'tooltipClass': 'amigo-searchbar-tooltip-style'
	};
	jQuery('.bbop-js-tooltip').tooltip(tt_args);

	//
	ll('Completed render!');
	ll('Done!');
    }
19959
function Graphics()
{
    Container.call(this);

    /**
     * The alpha value used when filling the Graphics object.
     *
     * @member {number}
     * @default 1
     */
    this.fillAlpha = 1;

    /**
     * The width (thickness) of any lines drawn.
     *
     * @member {number}
     * @default 0
     */
    this.lineWidth = 0;

    /**
     * The color of any lines drawn.
     *
     * @member {string}
     * @default 0
     */
    this.lineColor = 0;

    /**
     * Graphics data
     *
     * @member {GraphicsData[]}
     * @private
     */
    this.graphicsData = [];

    /**
     * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The previous tint applied to the graphic shape. Used to compare to the current tint and check if theres change.
     *
     * @member {number}
     * @private
     * @default 0xFFFFFF
     */
    this._prevTint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the graphic shape. Apply a value of blendModes.NORMAL to reset the blend mode.
     *
     * @member {number}
     * @default CONST.BLEND_MODES.NORMAL;
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * Current path
     *
     * @member {GraphicsData}
     * @private
     */
    this.currentPath = null;

    /**
     * Array containing some WebGL-related properties used by the WebGL renderer.
     *
     * @member {object<number, object>}
     * @private
     */
    // TODO - _webgl should use a prototype object, not a random undocumented object...
    this._webGL = {};

    /**
     * Whether this shape is being used as a mask.
     *
     * @member {boolean}
     */
    this.isMask = false;

    /**
     * The bounds' padding used for bounds calculation.
     *
     * @member {number}
     */
    this.boundsPadding = 0;

    /**
     * A cache of the local bounds to prevent recalculation.
     *
     * @member {Rectangle}
     * @private
     */
    this._localBounds = new math.Rectangle(0,0,1,1);

    /**
     * Used to detect if the graphics object has changed. If this is set to true then the graphics
     * object will be recalculated.
     *
     * @member {boolean}
     * @private
     */
    this.dirty = true;

    /**
     * Used to detect if the WebGL graphics object has changed. If this is set to true then the
     * graphics object will be recalculated.
     *
     * @member {boolean}
     * @private
     */
    this.glDirty = false;

    this.boundsDirty = true;

    /**
     * Used to detect if the cached sprite object needs to be updated.
     *
     * @member {boolean}
     * @private
     */
    this.cachedSpriteDirty = false;
}
1217295
function draw() {
    const options = {
      start: timeframeStartNode.value,
      end: timeframeEndNode.value,
      latitude: latNode.value,
      longitude: lngNode.value,
      radius: GEO.miles,
      zoom: GEO.zoom
    };

    const end = (options['end']) ? new Date(Date.parse(options['end'])) : new Date();
    const start = (options['start']) ? new Date(Date.parse(options['start'])) : new Date(end.getFullYear(), end.getMonth(), end.getDate() - 14);

    const rad = (options['radius']) ? parseFloat(options['radius']) : false;
    const lat = (options['latitude']) ? parseFloat(options['latitude']) : false;
    const lng = (options['longitude']) ? parseFloat(options['longitude']) : false;

    let geoFilter = [];
    if (lat && lng && rad) {
      geoFilter.push({
        property_name: 'keen.location.coordinates',
        operator: 'within',
        property_value: {
          coordinates: [parseFloat(options['longitude']), parseFloat(options['latitude'])],
          max_distance_miles: parseFloat(options['radius'])
        }
      });
    };

    const baseParams = {
      timeframe: {
        start: start.toISOString(),
        end: end.toISOString()
      },
      filters: geoFilter
    };

    // Fetch events within geo target
    const scoped_events = client.query('select_unique', {
      event_collection: 'user_action',
      target_property: 'keen.location.coordinates',
      timeframe: baseParams.timeframe,
      filters: baseParams.filters
    });
    client.run(scoped_events, (err, res) => {
      activeMapData.clearLayers();
      Keen.utils.each(res.result, coord => {
        const em = L.marker(new L.LatLng(coord[1], coord[0]), {
          icon: L.mapbox.marker.icon({
            'marker-color': '#00bbde'
          })
        }).addTo(activeMapData);;
      });
    });



    // Sample queries
    // groupBy not supported for Geo Filters

    const hearts = client.query('median', {
      event_collection: 'user_action',
      interval: 'daily',
      target_property: 'bio_sensors.heart_rate',
      timeframe: baseParams.timeframe,
      filters: baseParams.filters
    });

    const daily_median_heartrate = new KeenDataviz({
      container: '#chart-01',
      title: 'Daily Median Heart Rate',
      type: 'area',
      colors: ['#fe6672'],
    })

    client
      .run(hearts)
      .then(res => {
        daily_median_heartrate
          .data(res)
          .render()
      });


    const activations = client.query('count', {
      event_collection: 'activations',
      interval: 'daily',
      target_property: 'bio_sensors.heart_rate',
      timeframe: baseParams.timeframe,
      filters: baseParams.filters
    });

    const daily_activations = new KeenDataviz({
      container: '#chart-02',
      title: 'Daily Activations',
      type: 'area',
      colors: ['#fe6672'],
    });

    client
      .run(activations)
      .then(res => {
        daily_activations
          .data(res)
          .render()
      });


    const purchases = client.query('sum', {
      event_collection: 'purchases',
      target_property: 'order_price',
      interval: 'daily',
      timeframe: baseParams.timeframe,
      filters: baseParams.filters
    });

    const daily_purchases = new KeenDataviz({
      container: '#chart-03',
      title: 'Daily Purchases',
      type: 'area',
      colors: ['#eeb058'],
    });

    client
      .run(purchases)
      .then(res => {
        daily_purchases
          .data(res)
          .render()
      });

  }
464427
function drawBars() {
            let bars;

            if (isAnimated) {
                bars = svg.select('.chart-group').selectAll('.bar')
                    .data(dataZeroed);

                if (isHorizontal) {
                    drawHorizontalBars(bars);
                } else {
                    drawVerticalBars(bars);
                }

                bars = svg.select('.chart-group').selectAll('.bar')
                    .data(data);

                if (isHorizontal) {
                    drawAnimatedHorizontalBars(bars);
                } else {
                    drawAnimatedVerticalBars(bars);
                }

                // Exit
                bars.exit()
                    .transition()
                    .style('opacity', 0)
                    .remove();
            } else {
                bars = svg.select('.chart-group').selectAll('.bar')
                    .data(data);

                if (isHorizontal) {
                    drawHorizontalBars(bars);
                } else {
                    drawVerticalBars(bars);
                }

                // Exit
                bars.exit()
                    .remove();
            }

        }
1291393
function draw(renderer) {
         var color = renderer.getColor();
         var height = renderer.getHeight(); // draw the progress bar

         renderer.setColor("black");
         renderer.fillRect(this.pos.x, height / 2, this.width, this.height / 2);
         renderer.setColor("#55aa00");
         renderer.fillRect(this.pos.x, height / 2, this.progress, this.height / 2);
         renderer.setColor(color);
       }
542982
function () {
		
		var i,
			data = this.data,
			point,
			radius,
			radii = this.radii;
		
		// Run the parent method
		seriesTypes.scatter.prototype.translate.call(this);
		
		// Set the shape type and arguments to be picked up in drawPoints
		i = data.length;
		
		while (i--) {
			point = data[i];
			radius = radii ? radii[i] : 0; // #1737
			
			if (radius >= this.minPxSize / 2) {
				// Shape arguments
				point.shapeType = 'circle';
				point.shapeArgs = {
					x: point.plotX,
					y: point.plotY,
					r: radius
				};
				
				// Alignment box for the data label
				point.dlBox = {
					x: point.plotX - radius,
					y: point.plotY - radius,
					width: 2 * radius,
					height: 2 * radius
				};
			} else { // below zThreshold
				point.shapeArgs = point.plotY = point.dlBox = UNDEFINED; // #1691
			}
		}
	}
601120
function drawBullet() {
            if (rangesEl) {
                rangesEl.remove();
                measuresEl.remove();
                markersEl.remove();
            }

            rangesEl = svg.select('.chart-group')
              .selectAll('rect.range')
              .data(ranges)
              .enter()
                .append('rect')
                  .attr('fill', rangeColor)
                  .attr('opacity', (d, i) => rangeOpacityScale[i])
                  .attr('class', (d, i) => `range r${i}`)
                  .attr('width', barWidth)
                  .attr('height', chartHeight)
                  .attr('x', isReverse ? xScale : 0);

            measuresEl = svg.select('.chart-group')
              .selectAll('rect.measure')
              .data(measures)
              .enter()
                .append('rect')
                  .attr('fill', measureColor)
                  .attr('fill-opacity', (d, i) => measureOpacityScale[i])
                  .attr('class', (d, i) => `measure m${i}`)
                  .attr('width', barWidth)
                  .attr('height', getMeasureBarHeight)
                  .attr('x', isReverse ? xScale : 0)
                  .attr('y', getMeasureBarHeight);

            markersEl = svg.select('.chart-group')
              .selectAll('line.marker-line')
              .data(markers)
              .enter()
                .append('line')
                  .attr('class', 'marker-line')
                  .attr('stroke', measureColor)
                  .attr('stroke-width', markerStrokeWidth)
                  .attr('opacity', measureOpacityScale[0])
                  .attr('x1', xScale)
                  .attr('x2', xScale)
                  .attr('y1', 0)
                  .attr('y2', chartHeight);
        }
305766
function drawChart(canvas, data) {
        var ctx = canvas.getContext('2d'),
            color = 'rgba(0, 0, 0, 0.75)',
            height = canvas.height - 2,
            width = canvas.width,
            total = data.length,
            max = Math.max.apply(Math, data),
            xstep = 1,
            ystep = max / height,
            x = 0,
            y = height - data[0] / ystep;

        ctx.clearRect(0, 0, width, height);
        ctx.beginPath();
        ctx.strokeStyle = color;
        ctx.moveTo(x, y);

        for (var i = 1; i < total; i++) {
            x += xstep;
            y = height - data[i] / ystep + 1;
            ctx.moveTo(x, height);
            ctx.lineTo(x, y);
        }

        ctx.stroke();
    }
186451
function drawStackedAreas() {
            // Not ideal, we need to figure out how to call exit for nested elements
            if (series) {
                svg.selectAll('.layer-container').remove();
                svg.selectAll('.layer').remove();
                svg.selectAll('.area-outline').remove();
            }

            if (isUsingFakeData) {
                drawEmptyDataLine();

                return;
            }

            area = d3Shape.area()
                .curve(curveMap[areaCurve])
                .x(({data})=> xScale(data.date))
                .y0((d) => yScale(d[0]))
                .y1((d) => yScale(d[1]));

            areaOutline = d3Shape.line()
                .curve(area.curve())
                .x(({data}) => xScale(data.date))
                .y((d) => yScale(d[1]));

            if (isAnimated) {
                series = svg.select('.chart-group').selectAll('.layer')
                    .data(layersInitial, getName)
                    .enter()
                      .append('g')
                        .classed('layer-container', true);

                series
                  .append('path')
                    .attr('class', 'layer')
                    .attr('d', area)
                    .style('opacity', areaOpacity)
                    .style('fill', ({key}) => categoryColorMap[key]);

                series
                  .append('path')
                    .attr('class', 'area-outline')
                    .attr('d', areaOutline)
                    .style('stroke', ({key}) => categoryColorMap[key]);

                // Update
                svg.select('.chart-group').selectAll('.layer')
                    .data(layers)
                    .transition()
                    .delay((_, i) => areaAnimationDelays[i])
                    .duration(areaAnimationDuration)
                    .ease(ease)
                    .attr('d', area)
                    .style('opacity', areaOpacity)
                    .style('fill', ({key}) => categoryColorMap[key]);

                svg.select('.chart-group').selectAll('.area-outline')
                    .data(layers)
                    .transition()
                    .delay( (_, i) => areaAnimationDelays[i])
                    .duration(areaAnimationDuration)
                    .ease(ease)
                    .attr('d', areaOutline);

            } else {
                series = svg.select('.chart-group').selectAll('.layer')
                    .data(layers)
                    .enter()
                      .append('g')
                        .classed('layer-container', true);

                series
                  .append('path')
                    .attr('class', 'layer')
                    .attr('d', area)
                    .style('opacity', areaOpacity)
                    .style('fill', ({key}) => categoryColorMap[key]);

                series
                  .append('path')
                    .attr('class', 'area-outline')
                    .attr('d', areaOutline)
                    .style('stroke', ({key}) => categoryColorMap[key]);


                // Update
                svg.select('.chart-group').selectAll('.layer')
                    .attr('d', area)
                    .style('opacity', areaOpacity)
                    .style('fill', ({key}) => categoryColorMap[key]);

                svg.select('.chart-group').selectAll('.area-outline')
                    .attr('class', 'area-outline')
                    .attr('d', areaOutline)
                    .style('stroke', ({key}) => categoryColorMap[key]);
            }

            if (!hasOutline) {
                svg.select('.chart-group')
                  .selectAll('.area-outline')
                  .style('display', 'none');
            }

            // Exit
            series.exit()
                .transition()
                .style('opacity', 0)
                .remove();
        }
785603
function DrawBars() {

    if ($this->data_type != "text-data") {
      $this->DrawError('Bar plots must be text-data: use function SetDataType("text-data")');
    }

    $xadjust = ($this->records_per_group * $this->record_bar_width )/4;

    reset($this->data_values);
    while (list($j, $row) = each($this->data_values)) {

      $color_index = 0;
      $colbarcount = 0;
      $x_now = $this->xtr($j+.5);

      while (list($k, $v) = each($row)) {
        if ($k == 0) {
          //Draw Data Labels
          $xlab = SubStr($v,0,$this->x_datalabel_maxlength);
          $this->DrawXDataLabel($xlab,$x_now);
        } else {
          // Draw Bars ($v)
          $x1 = $x_now - $this->data_group_space + ($k-1)*$this->record_bar_width;
          $x2 = $x1 + $this->record_bar_width*$this->bar_width_adjust;

          if ($v < $this->x_axis_position) {
            $y1 = $this->ytr($this->x_axis_position);
            $y2 = $this->ytr($v);
          } else {
            $y1 = $this->ytr($v);
            $y2 = $this->ytr($this->x_axis_position);
          }

          if ($color_index >= count($this->ndx_data_color)) $color_index=0;
          if ($colbarcount >= count($this->ndx_data_border_color)) $colbarcount=0;
          $barcol = $this->ndx_data_color[$color_index];
          $bordercol = $this->ndx_data_border_color[$colbarcount];

          if ((strval($v) != "") ) {   //Allow for missing Y data
            if ($this->shading > 0) {
              for($i=0;$i<($this->shading);$i++) {
              //Shading set in SetDefaultColors
              ImageFilledRectangle($this->img, $x1+$i, $y1-$i, $x2+$i, $y2-$i, $this->ndx_i_light);
              }
            }

            ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $barcol);
            ImageRectangle($this->img, $x1, $y1, $x2, $y2, $bordercol);
            if ($this->draw_data_labels == '1') {  //ajo
              $y1 = $this->ytr($this->label_scale_position * $v);
              //$this->DrawDataLabel($v,$j + .5,$v*$this->label_scale_position);
              $this->DrawText($this->small_font, $this->x_label_angle,
                $x1+$this->record_bar_width/2, $y1, $this->ndx_label_color, $this->x_label_ttffont_size, $v,'center','top');
            }
          }

          $color_index++;
          $colbarcount++;
        }
      }
    }
  }
18070
function PiePiece(data, idx) {

    graphic.Group.call(this);

    var sector = new graphic.Sector({
        z2: 2
    });
    var polyline = new graphic.Polyline();
    var text = new graphic.Text();
    this.add(sector);
    this.add(polyline);
    this.add(text);

    this.updateData(data, idx, true);
}
551178
function draw (type) { // TODO: use type
        if (cache !== null) {
            return new Promise((resolve) => {
                resolve(cache);
            });
        }
        return new Promise((resolve, reject) => {
            const images = [];

            // Wait for resourse loading
            onLoadPromise.then(() => {
                RED.nodes.import(flow);
                const workspaceIds = Object.keys(RED.workspaces.tabs());
                drawWorkspacesWithIds(workspaceIds).catch((err) => { console.error(err); });
            });
            
            function drawWorkspacesWithIds (ids) {
                const id = ids.pop();
                if (!id) {
                    return;
                } else {
                    RED.workspaces.show(id);
                    const el = RED.view.redraw(true);
                    const unmute = mute();
                    return svgSaver.svgAsDataUri(el).then(function (uri) {
                        unmute();
                        images.push(uri);
                        const promise = drawWorkspacesWithIds(ids);
                        if (promise) {
                            promise.catch((err) => { reject(err); });
                        } else {
                            resolve(images);
                        }
                    });
                }
            }
        }).then((results) => cache = results);
    }
1180924
function() {
    var x_start = this.bar_padding + this.options.plot_padding,
        step = this.step;
    if (this.grouped) {
      step = step * this.group_size;
      x_start = ((this.bar_width * this.group_size) + (this.bar_padding * this.group_size)) / 2
      x_start = this.roundValue(x_start, 0);
    }
    this.drawMarkers(this.options.labels, [1, 0], step, x_start, [0, (this.options.font_size + 7) * -1]);
  }