@Override
	public String getSVG( HashMap<String, Double> chartMetrics, HashMap<String, Object> axisMetrics, ChartSeries s )
	{
		double x = chartMetrics.get( "x" );    // + (!yAxisReversed?0:w);	// x is constant at x origin unless reversed
		double y = chartMetrics.get( "y" );
		double w = chartMetrics.get( "w" );
		double h = chartMetrics.get( "h" );
		double max = chartMetrics.get( "max" );
		double min = chartMetrics.get( "min" );
		Object[] categories = s.getCategories();
		ArrayList series = s.getSeriesValues();
		String[] seriescolors = s.getSeriesBarColors();
		String[] legends = s.getLegends();
		if( series.size() == 0 )
		{
			log.error( "Line.getSVG: error in series" );
			return "";
		}

		// x value for each point= w/(ncategories + 1) 1st one is xv*2 then increases from there
		// y value for each point= h/YMAX 
		StringBuffer svg = new StringBuffer();
		// get data labels, marker formats, series colors
		int n = series.size();
		int[] dls = getDataLabelInts(); // get array of data labels (can be specific per series ...)
		int[] markers = getMarkerFormats();
		double xfactor = 0;    //
		double yfactor = 0;
		if( categories.length != 0 )
		{
			xfactor = w / (categories.length);    // w/#categories
		}
		else
		{
			xfactor = w;
		}
		if( max != 0 )
		{
			yfactor = h / max;    // h/YMAXSCALE
		}
		svg.append( "<g>\r\n" );
		// define marker shapes for later use 
		svg.append( MarkerFormat.getMarkerSVGDefs() );
		// for each series 
		for( int i = 0; i < n; i++ )
		{
			// each visible line on the chart consists of two lines- 1 black, 1 color
			String points = "";
			String labels = "";
			double[] curseries = (double[]) series.get( i );
			String[] curranges = (String[]) s.getSeriesRanges().get( i );
			for( int j = 0; j < curseries.length; j++ )
			{
				points += ((x) + ((j + .5) * xfactor)) + "," + ((y + h) - (curseries[j] * yfactor));
				points += " ";
				String l = getSVGDataLabels( dls, axisMetrics, curseries[j], 0, i, legends, categories[j].toString() );
				if( l != null )
				{
					double xx = (2 + (x) + ((j + .5) * xfactor));
					if( markers[i] > 0 )
					{
						xx += 10;    // scoot over for markers
					}
					labels += "<text x='" + xx + "' y='" + (((y + h) - (curseries[j] * yfactor))) +
							"' " + getDataLabelFontSVG() + ">" + l + "</text>\r\n";
				}
			}
			// 1st line is black
			svg.append( "<polyline " + getScript( "" ) + " fill='none' fill-opacity='0' " + getStrokeSVG( 4, getDarkColor() ) + " points='" + points + "'" + "/>\r\n" );
			// 2nd line is the series color
			svg.append( "<polyline " + getScript( "" ) + "  id='series_" + (i + 1) + "' fill='none' fill-opacity='0' stroke='" + seriescolors[i] + "' stroke-opacity='1' stroke-width='3' stroke-linecap='butt' stroke-linejoin='miter' stroke-miterlimit='4'" +
					            " points='" + points + "'" +
					            "/>\r\n" );
			// Markers, if any, along data points in series
			if( markers[i] > 0 )
			{
				String[] markerpoints = points.split( " " );
				for( String markerpoint : markerpoints )
				{
					String[] xy = markerpoint.split( "," );
					double xx = Double.valueOf( xy[0] );
					double yy = Double.valueOf( xy[1] );
					svg.append( MarkerFormat.getMarkerSVG( xx, yy, seriescolors[i], markers[i] ) + "\r\n" );
				}
			}
			// data labels, if any, after lines and markers  
			svg.append( labels );
		}

		svg.append( "</g>\r\n" );
		return svg.toString();
	}