Type xlsxChart = Class
	///缺省构造函数
	Function Create(sheet,excel); overload;
	Begin
		excel_ := excel;
		sheetName_ := sheet;
		chartId_ := excel_.WorkBook().GetFilesCount('xl/charts/chart') + 1;
		[rid, drawingFileName, sheetFileName_, relsfile] := excel_.WorkBook().GetRelationshipRid(sheet, '../drawings/drawing');
		if drawingFileName = '' then Begin
			rid++;
			drawingRID_ := excel_.WorkBook().GetFilesCount('xl/drawings/drawing') + 1;
			drawingFileName := '../drawings/drawing' + inttostr(drawingRID_) + '.xml';
			xlDrawingFileName_ := 'xl/drawings/drawing' + inttostr(drawingRID_) + '.xml';
			excel_.Zip().Add(xlDrawingFileName_, excel_.XmlObj().XmlHeader() + '<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"></xdr:wsDr>');
			excel_.WorkBook().AddRelationshipRid(relsfile, drawingFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', 'rId' + inttostr(rid));
			excel_.WorkBook().AddContentType('application/vnd.openxmlformats-officedocument.drawing+xml', '/' + xlDrawingFileName_);
			//<drawing r:id="rId1"/>
			sheetXmlObj := excel_.WorkBook().GetXmlFileObj(sheetFileName_);
			node := sheetXmlObj.FirstChild('worksheet').InsertEndChild('element', 'drawing');
			node.SetAttribute('r:id', 'rId' + inttostr(rid));
		End
		else Begin
			xlDrawingFileName_ := 'xl/drawings/' + ExtractFileName(drawingFileName);
			s := RightStr(xlDrawingFileName_, length(xlDrawingFileName_) - 19);
			drawingRID_ := strtoint(leftstr(s, length(s) - 4));
		End;
		drawingXmlObj_ := excel_.WorkBook().GetXmlFileObj(xlDrawingFileName_);
		drawingRels := 'xl/drawings/_rels/drawing' + inttostr(drawingRID_) + '.xml.rels';
		if not excel_.WorkBook().FileIsExist(drawingRels) then Begin
			excel_.Zip().Add(drawingRels, excel_.XmlObj().XmlHeader() + '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"/>');
		End
		drawingRelsObj := excel_.WorkBook().GetXmlFileObj(drawingRels);
		[chartRid_, find] := class(xlsxXml).FindRelationshipRid(drawingRelsObj, '');
		excel_.WorkBook().AddRelationshipRid(drawingRels, '../charts/chart'+inttostr(chartId_)+'.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' + inttostr(chartRid_ + 1));
		xlChartFileName_ := 'xl/charts/chart'+inttostr(chartId_)+'.xml';
		excel_.WorkBook().AddContentType('application/vnd.openxmlformats-officedocument.drawingml.chart+xml', '/' + xlChartFileName_);
	End;
	
	class Function NewObject(sheet, excel);
	Begin
		excel_ := excel;
		o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
		if not ifObj(o, chart) then return 0;
		return new xlsxChart(sheet, excel);
	End;
	
	Function AddChart(range, chart);
	Begin
		a := str2array(range,':');
		if length(a) <> 2 then return array(1,'Invalid params.');
		[err1, col1,row1] := excel_.CellNameToCoordinates(a[0]);
		[err2, col2,row2] := excel_.CellNameToCoordinates(a[1]);
		if err1 or err2 then return array(1,'Invalid params.');
		o := TOfficeObj('TtwoCellAnchor');
		o.XFrom.Col := col1 - 1;
		o.XFrom.ColOff := chart.BegColOff ? chart.BegColOff : 0;
		o.XFrom.Row := row1 - 1;
		o.XFrom.RowOff := chart.BegRowOff ? chart.BegRowOff : 0;

		o.XTo.Col := col2;
		o.XTo.ColOff := chart.EndColOff ? chart.EndColOff : 0;
		o.XTo.Row := row2;
		o.XTo.RowOff := chart.EndRowOff ? chart.EndRowOff : 0;

		o.GraphicFrame.GraphicFramePr.Name := chart.Name ? chart.Name : 'Chart' + inttostr(chartId_);
		o.GraphicFrame.GraphicFramePr.Id := getcNvPrID(drawingXmlObj_);

		o.GraphicFrame.XFrm.Off.X := 0;
		o.GraphicFrame.XFrm.Off.Y := 0;
		o.GraphicFrame.XFrm.Ext.Cx := 0;
		o.GraphicFrame.XFrm.Ext.Cy := 0;

		o.GraphicFrame.Graphic.GraphicData.uri := 'http://schemas.openxmlformats.org/drawingml/2006/chart';
		o.GraphicFrame.Graphic.GraphicData.Rid := 'rId' + inttostr(chartRid_ + 1);
		o.GraphicFrame.Graphic.GraphicData.R := 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
		o.GraphicFrame.Graphic.GraphicData.C := 'http://schemas.openxmlformats.org/drawingml/2006/chart';
		node := drawingXmlObj_.FirstChild('xdr:wsDr').InsertEndChild(o.Marshal());
		
		plotArea := getPlotArea(chart);//设置图形
		chartXml := '<?xml version="1.0" encoding="UTF-8"?>
<chartSpace
    xmlns="http://schemas.openxmlformats.org/drawingml/2006/chart"
    xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
    <date1904 val="0"></date1904>
    <lang val="en-US"></lang>
    <roundedCorners val="0"></roundedCorners>
    <chart>
        <title>
            <tx>
                <rich>
                    <a:bodyPr anchorCtr="false" rot="0" spcFirstLastPara="false"></a:bodyPr>
                    <a:p>
                        <a:pPr>
                            <a:defRPr b="false" baseline="0" i="false" kern="1200" spc="0" strike="noStrike" sz="1400" u="none">
                                <a:solidFill>
                                    <a:schemeClr val="tx1">
                                        <a:lumMod val="65000"></a:lumMod>
                                        <a:lumOff val="35000"></a:lumOff>
                                    </a:schemeClr>
                                </a:solidFill>
                                <a:latin typeface="+mn-lt"></a:latin>
                                <a:ea typeface="+mn-ea"></a:ea>
                                <a:cs typeface="+mn-cs"></a:cs>
                            </a:defRPr>
                        </a:pPr>
                        <a:r>
                            <a:rPr altLang="en-US" b="false" baseline="0" i="false" kern="0" lang="en-US" spc="0"></a:rPr>
                            <a:t>Fruit 2D Column Chart</a:t>
                        </a:r>
                    </a:p>
                </rich>
            </tx>
            <overlay val="0"></overlay>
            <spPr></spPr>
            <txPr>
                <a:bodyPr anchorCtr="false" rot="0" spcFirstLastPara="false"></a:bodyPr>
                <a:p>
                    <a:pPr>
                        <a:defRPr b="false" baseline="0" i="false" kern="1200" spc="0" strike="noStrike" sz="14000" u="none"></a:defRPr>
                    </a:pPr>
                    <a:endParaRPr lang="en-US"></a:endParaRPr>
                </a:p>
            </txPr>
        </title>
        <view3D>
            <rotX val="0"></rotX>
            <rotY val="0"></rotY>
            <rAngAx val="0"></rAngAx>
            <perspective val="0"></perspective>
        </view3D>
        <floor>
            <thickness val="0"></thickness>
        </floor>
        <sideWall>
            <thickness val="0"></thickness>
        </sideWall>
        <backWall>
            <thickness val="0"></thickness>
        </backWall>
		<plotArea/>
        <legend>
            <legendPos val="l"></legendPos>
            <overlay val="0"></overlay>
        </legend>
        <plotVisOnly val="0"></plotVisOnly>
        <dispBlanksAs val="zero"></dispBlanksAs>
        <showDLblsOverMax val="0"></showDLblsOverMax>
    </chart>
    <spPr>
        <a:solidFill>
            <a:schemeClr val="bg1"></a:schemeClr>
        </a:solidFill>
        <a:ln algn="ctr" cap="flat" cmpd="sng" w="9525">
            <a:solidFill>
                <a:schemeClr val="tx1">
                    <a:lumMod val="15000"></a:lumMod>
                    <a:lumOff val="85000"></a:lumOff>
                </a:schemeClr>
            </a:solidFill>
        </a:ln>
    </spPr>
    <printSettings>
        <pageMargins b="0.75" footer="0.3" header="0.3" l="0.7" r="0.7" t="0.7"></pageMargins>
    </printSettings>
</chartSpace>';
		excel_.Zip().Add(xlChartFileName_, chartXml);
		obj := excel_.WorkBook().GetXmlFileObj(xlChartFileName_);
		task := array(('chartSpace/chart/title/tx/rich/a:p/a:r/a:t', 'pcdata', chart.Title),
					('chartSpace/chart/legend/legendPos', 'val', getLegendPosition(chart.Legend.Position)),
					('chartSpace/chart/dispBlanksAs', 'val', chart.ShowBlanksAs),
					('chartSpace/chart/legend', 'Del', chart.Legend.None),
					('chartSpace/chart/plotArea', 'unmarshal', plotArea.Marshal()),
					('chartSpace/chart/view3D', 'unmarshal', getview3D(chart).Marshal())
					);
		for i:=0 to length(task)-1 do Begin
			class(xlsxXml).SetNodeValue(obj, task[i]);
		End;
	End;
private	
	Function getview3D(chart);
	Begin
		view3D := TOfficeObj('TView3D');
		chartView3DRotX := array(
			'area':                        0,
			'areastacked':                 0,
			'areapercentstacked':          0,
			'area3d':                      15,
			'area3dstacked':               15,
			'area3dpercentstacked':        15,
			'bar':                         0,
			'barstacked':                  0,
			'barpercentstacked':           0,
			'bar3dclustered':              15,
			'bar3dstacked':                15,
			'bar3dpercentstacked':         15,
			'bar3dconeclustered':          15,
			'bar3dconestacked':            15,
			'bar3dconepercentstacked':     15,
			'bar3dpyramidclustered':       15,
			'bar3dpyramidstacked':         15,
			'bar3dpyramidpercentstacked':  15,
			'bar3dcylinderclustered':      15,
			'bar3dcylinderstacked':        15,
			'bar3dcylinderpercentstacked': 15,
			'col':                         0,
			'colstacked':                  0,
			'colpercentstacked':           0,
			'col3d':                       15,
			'col3dclustered':              15,
			'col3dstacked':                15,
			'col3dpercentstacked':         15,
			'col3dcone':                   15,
			'col3dconeclustered':          15,
			'col3dconestacked':            15,
			'col3dconepercentstacked':     15,
			'col3dpyramid':                15,
			'col3dpyramidclustered':       15,
			'col3dpyramidstacked':         15,
			'col3dpyramidpercentstacked':  15,
			'col3dcylinder':               15,
			'col3dcylinderclustered':      15,
			'col3dcylinderstacked':        15,
			'col3dcylinderpercentstacked': 15,
			'doughnut':                    0,
			'line':                        0,
			'pie':                         0,
			'pie3d':                       30,
			'pieofpiechart':               0,
			'barofpiechart':               0,
			'radar':                       0,
			'scatter':                     0,
			'surface3d':                   15,
			'wireframesurface3d':          15,
			'contour':                     90,
			'wireframecontour':            90);
		chartView3DRotY := array(
			'area':                        0,
			'areastacked':                 0,
			'areapercentstacked':          0,
			'area3d':                      20,
			'area3dstacked':               20,
			'area3dpercentstacked':        20,
			'bar':                         0,
			'barstacked':                  0,
			'barpercentstacked':           0,
			'bar3dclustered':              20,
			'bar3dstacked':                20,
			'bar3dpercentstacked':         20,
			'bar3dconeclustered':          20,
			'bar3dconestacked':            20,
			'bar3dconepercentstacked':     20,
			'bar3dpyramidclustered':       20,
			'bar3dpyramidstacked':         20,
			'bar3dpyramidpercentstacked':  20,
			'bar3dcylinderclustered':      20,
			'bar3dcylinderstacked':        20,
			'bar3dcylinderpercentstacked': 20,
			'col':                         0,
			'colstacked':                  0,
			'colpercentstacked':           0,
			'col3d':                       20,
			'col3dclustered':              20,
			'col3dstacked':                20,
			'col3dpercentstacked':         20,
			'col3dcone':                   20,
			'col3dconeclustered':          20,
			'col3dconestacked':            20,
			'col3dconepercentstacked':     20,
			'col3dpyramid':                20,
			'col3dpyramidclustered':       20,
			'col3dpyramidstacked':         20,
			'col3dpyramidpercentstacked':  20,
			'col3dcylinder':               20,
			'col3dcylinderclustered':      20,
			'col3dcylinderstacked':        20,
			'col3dcylinderpercentstacked': 20,
			'doughnut':                    0,
			'line':                        0,
			'pie':                         0,
			'pie3d':                       0,
			'pieofpiechart':               0,
			'barofpiechart':               0,
			'radar':                       0,
			'scatter':                     0,
			'surface3d':                   20,
			'wireframesurface3d':          20,
			'contour':                     0,
			'wireframecontour':            0);
		chartView3DPerspective  := array(
			'contour':          0,
			'wireframecontour': 0);
		chartView3DRAngAx  := array(
			'area':                        0,
			'areastacked':                 0,
			'areapercentstacked':          0,
			'area3d':                      1,
			'area3dstacked':               1,
			'area3dpercentstacked':        1,
			'bar':                         0,
			'barstacked':                  0,
			'barpercentstacked':           0,
			'bar3dclustered':              1,
			'bar3dstacked':                1,
			'bar3dpercentstacked':         1,
			'bar3dconeclustered':          1,
			'bar3dconestacked':            1,
			'bar3dconepercentstacked':     1,
			'bar3dpyramidclustered':       1,
			'bar3dpyramidstacked':         1,
			'bar3dpyramidpercentstacked':  1,
			'bar3dcylinderclustered':      1,
			'bar3dcylinderstacked':        1,
			'bar3dcylinderpercentstacked': 1,
			'col':                         0,
			'colstacked':                  0,
			'colpercentstacked':           0,
			'col3d':                       1,
			'col3dclustered':              1,
			'col3dstacked':                1,
			'col3dpercentstacked':         1,
			'col3dcone':                   1,
			'col3dconeclustered':          1,
			'col3dconestacked':            1,
			'col3dconepercentstacked':     1,
			'col3dpyramid':                1,
			'col3dpyramidclustered':       1,
			'col3dpyramidstacked':         1,
			'col3dpyramidpercentstacked':  1,
			'col3dcylinder':               1,
			'col3dcylinderclustered':      1,
			'col3dcylinderstacked':        1,
			'col3dcylinderpercentstacked': 1,
			'doughnut':                    0,
			'line':                        0,
			'pie':                         0,
			'pie3d':                       0,
			'pieofpiechart':               0,
			'barofpiechart':               0,
			'radar':                       0,
			'scatter':                     0,
			'surface3d':                   0,
			'wireframesurface3d':          0,
			'contour':                     0,
			'bubble':                      0,
			'bubble3d':                    0);
		view3D.RotX := chartView3DRotX[chart.Type];
		view3D.RotY := chartView3DRotY[chart.Type];
		view3D.Perspective := chartView3DPerspective[chart.Type];
		view3D.RAngAx := chartView3DRAngAx[chart.Type];
		return view3D;
	End;
	
	Function getLegendPosition(t);
	Begin
		m := array("bottom":    "b",
			"left":      "l",
			"right":     "r",
			"top":       "t",
			"top_right": "tr");
		return m[t];
	End;
	
	Function getcNvPrID(obj);
	Begin
		cnt := 2;
		node := obj.FirstChild('xdr:wsDr');
		if ifObj(node) then Begin
			node := node.FirstChild();
			while ifObj(node) do Begin
				if node.GetName() in array('xdr:oneCellAnchor', 'xdr:twoCellAnchor') then
					cnt++;
				node := node.NextElement();
			End;
		End;
		return cnt;
	End;
	
	Function getPlotArea(chart);
	Begin
		o := TOfficeObj('TplotArea');
		chart.Type := lowercase(chart.Type);
		case chart.Type of
		'area','areastacked','areapercentstacked','area3d','area3dstacked','area3dpercentstacked','bar','barstacked','barpercentstacked',
		'bar3dclustered','bar3dstacked','bar3dpercentstacked','bar3dconeclustered','bar3dconestacked','bar3dconepercentstacked',
		'bar3dpyramidclustered','bar3dpyramidstacked','bar3dpyramidpercentstacked','bar3dcylinderclustered','bar3dcylinderstacked',
		'bar3dcylinderpercentstacked','col','colstacked','colpercentstacked','col3d','col3dclustered','col3dstacked','col3dpercentstacked',
		'col3dcone','col3dconeclustered','col3dconestacked','col3dconepercentstacked','col3dpyramid','col3dpyramidclustered',
		'col3dpyramidstacked','col3dpyramidpercentstacked','col3dcylinder','col3dcylinderclustered','col3dcylinderstacked',
		'col3dcylinderpercentstacked','bubble','bubble3d':
			drawBaseChart(o, chart);
		'doughnut':
		Begin
			drawExtChart(o, chart, 'doughnutChart');
			o.Chart.HoleSize := 75;
		End
		'line':
			drawLineChart(o, chart);
		'pie3d':
			drawExtChart(o, chart, 'pie3DChart');
		'pie':
			drawExtChart(o, chart, 'pieChart');
		'pieofpiechart':
		Begin
			drawExtChart(o, chart, 'ofPieChart');
			o.Chart.OfPieType := 'pie';
		End
		'barofpiechart':
		Begin
			drawExtChart(o, chart, 'ofPieChart');
			o.Chart.OfPieType := 'bar';
		End
		'radar':
			drawRadarChart(o, chart);
		'scatter':
			drawScatterChart(o, chart);
		'surface3d','wireframesurface3d':
			drawSurface3DChart(o, chart, 'surface3DChart');
		'contour','wireframecontour':
			drawSurface3DChart(o, chart, 'surfaceChart');
		End;
		return o;
	End;
	
	Function drawSurface3DChart(o, chart, name);
	Begin
		o.Chart.NodeName := name;
		setChartSer(o, chart);
		o.Chart.Axid := 754001152;
		o.Chart.Axid2 := 753999904;
		o.Chart.Axid3 := 832256642;
		setCatAx(o.CatAx, chart);
		setValAx(o.ValAx, chart);
		setSerAx(o.SerAx, chart);
		if chart.Type in array( 'wireframesurface3d', 'wireframecontour' ) then 
			o.Chart.Wireframe := true;
	End;

	Function drawScatterChart(o, chart);
	Begin
		o.Chart.NodeName := 'scatterChart';
		o.Chart.ScatterStyle := 'smoothMarker';
		o.Chart.VaryColors := false;
		setChartSer(o, chart);
		setDLbls(o.Chart.DLbls, chart);
		o.Chart.Axid := 754001152;
		o.Chart.Axid2 := 753999904;
		setCatAx(o.CatAx, chart);
		setValAx(o.ValAx, chart);
	End;

	Function drawRadarChart(o, chart);
	Begin
		o.Chart.NodeName := 'radarChart';
		o.Chart.RadarStyle := 'marker';
		o.Chart.VaryColors := false;
		setChartSer(o, chart);
		setDLbls(o.Chart.DLbls, chart);
		o.Chart.Axid := 754001152;
		o.Chart.Axid2 := 753999904;
		setCatAx(o.CatAx, chart);
		setValAx(o.ValAx, chart);
	End;
	
	Function drawExtChart(o, chart, name);
	Begin
		o.Chart.NodeName := name;
		o.Chart.VaryColors := chart.VaryColors;
		setChartSer(o, chart);
	End;

	Function drawLineChart(o, chart);
	Begin
		o.Chart.NodeName := 'lineChart';
		o.Chart.Grouping := getGrouping(chart.Type);
		o.Chart.VaryColors := false;
		setChartSer(o, chart);
		setDLbls(o.Chart.DLbls, chart);
		o.Chart.Smooth := false;
		o.Chart.Axid := 754001152;
		o.Chart.Axid2 := 753999904;
		setCatAx(o.CatAx, chart);
		setValAx(o.ValAx, chart);
	End;
	
	Function drawBaseChart(o, chart);
	Begin
		o.Chart.BarDir := getBarDir(chart.Type);
		o.Chart.Grouping := getGrouping(chart.Type);
		o.Chart.VaryColors := chart.VaryColors;
		o.Chart.Overlap := getVaryColors(chart.Type);
		o.Chart.Axid := 754001152;
		o.Chart.Axid2 := 753999904;
		o.Chart.NodeName := getChartName(chart.Type);
		setChartSer(o, chart);
		o.Chart.Shape := getSharp(chart.Type);
		setDLbls(o.Chart.DLbls, chart);
		setCatAx(o.CatAx, chart);
		setValAx(o.ValAx, chart);
	End;
	
	Function setSerAx(SerAx, chart);
	Begin
		SerAx.AxID := 832256642;
		SerAx.Scaling.Max := chart.YAxis.Max;
		SerAx.Scaling.Min := chart.YAxis.Min;
		CatAx.Scaling.Orientation := chart.YAxis.ReverseOrder ? 'maxMin' : 'minMax';
		SerAx.Del := chart.YAxis.None;
		SerAx.AxPos := chart.XAxis.ReverseOrder ? 't' : 'b';
		SerAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(SerAx.SpPr);
		drawPlotAreaTxPr(SerAx.TxPr);
		SerAx.CrossAx := 753999904;
	End;
	
	Function setCatAx(CatAx, chart);
	Begin
		CatAx.AxID := 754001152;
		CatAx.Scaling.Max := chart.XAxis.Max;
		CatAx.Scaling.Min := chart.XAxis.Min;
		CatAx.Scaling.Orientation := chart.XAxis.ReverseOrder ? 'maxMin' : 'minMax';
		CatAx.Del := chart.XAxis.None;
		CatAx.AxPos := chart.XAxis.ReverseOrder ? 't' : 'b';
		CatAx.NumFmt.FormatCode := 'General';
		CatAx.NumFmt.SourceLinked := true;
		CatAx.MajorTickMark := 'none';
		CatAx.MinorTickMark := 'none';
		CatAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(CatAx.SpPr);
		drawPlotAreaTxPr(CatAx.TxPr);
		CatAx.CrossAx := 753999904;
		CatAx.Crosses := 'autoZero';
		CatAx.Auto := true;
		CatAx.LblAlgn := 'ctr';
		CatAx.LblOffset := 100;
		CatAx.NoMultiLvlLbl := false;
		if chart.XAxis.MajorGridlines then
			drawPlotAreaSpPr(CatAx.MajorGridlines.SpPr);
		if chart.XAxis.MinorGridlines then
			drawPlotAreaSpPr(CatAx.MinorGridlines.SpPr);
		if chart.XAxis.TickLabelSkip then
			CatAx.TickLabelSkip := chart.XAxis.TickLabelSkip;
	End;
	
	Function setValAx(ValAx, chart);
	Begin
		ValAx.AxID := 753999904;
		ValAx.Scaling.Max := chart.YAxis.Max;
		ValAx.Scaling.Min := chart.YAxis.Min;
		if ifint(chart.YAxis.LogBase) and chart.YAxis.LogBase >= 2 and chart.YAxis.LogBase <= 1000 then
			ValAx.Scaling.LogBase := chart.YAxis.LogBase;
		ValAx.Scaling.Orientation := chart.YAxis.ReverseOrder ? 'maxMin' : 'minMax';
		ValAx.Del := chart.YAxis.None;
		ValAx.AxPos := chart.YAxis.ReverseOrder ? 'r' : 'l';
		ValAx.NumFmt.FormatCode := chartValAxNumFmtFormatCode(chart.Type);
		ValAx.NumFmt.SourceLinked := true;
		ValAx.MajorTickMark := 'none';
		ValAx.MinorTickMark := 'none';
		ValAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(ValAx.SpPr);
		drawPlotAreaTxPr(ValAx.TxPr);
		ValAx.CrossAx := 754001152;
		ValAx.Crosses := 'autoZero';
		ValAx.CrossBetween := chartValAxCrossBetween(chart.Type);
		if chart.XAxis.MajorGridlines then
			drawPlotAreaSpPr(ValAx.MajorGridlines.SpPr);
		if chart.XAxis.MinorGridlines then
			drawPlotAreaSpPr(ValAx.MinorGridlines.SpPr);
		ValAx.MajorUnit := chart.YAxis.MajorUnit;
		if chart.Type in array('contour', 'wireframecontour') then
			ValAx.TickLblPos := 'none';
	End;
	
	Function chartValAxCrossBetween(t);
	Begin
		m := array(
		'area':                        ’midCat’,
		'areastacked':                 ’midCat’,
		'areapercentstacked':          ’midCat’,
		'area3d':                      ’midCat’,
		'area3dstacked':               ’midCat’,
		'area3dpercentstacked':        ’midCat’,
		'bar':                         ’between’,
		'barstacked':                  ’between’,
		'barpercentstacked':           ’between’,
		'bar3dclustered':              ’between’,
		'bar3dstacked':                ’between’,
		'bar3dpercentstacked':         ’between’,
		'bar3dconeclustered':          ’between’,
		'bar3dconestacked':            ’between’,
		'bar3dconepercentstacked':     ’between’,
		'bar3dpyramidclustered':       ’between’,
		'bar3dpyramidstacked':         ’between’,
		'bar3dpyramidpercentstacked':  ’between’,
		'bar3dcylinderclustered':      ’between’,
		'bar3dcylinderstacked':        ’between’,
		'bar3dcylinderpercentstacked': ’between’,
		'col':                         ’between’,
		'colstacked':                  ’between’,
		'colpercentstacked':           ’between’,
		'col3d':                       ’between’,
		'col3dclustered':              ’between’,
		'col3dstacked':                ’between’,
		'col3dpercentstacked':         ’between’,
		'col3dcone':                   ’between’,
		'col3dconeclustered':          ’between’,
		'col3dconestacked':            ’between’,
		'col3dconepercentstacked':     ’between’,
		'col3dpyramid':                ’between’,
		'col3dpyramidclustered':       ’between’,
		'col3dpyramidstacked':         ’between’,
		'col3dpyramidpercentstacked':  ’between’,
		'col3dcylinder':               ’between’,
		'col3dcylinderclustered':      ’between’,
		'col3dcylinderstacked':        ’between’,
		'col3dcylinderpercentstacked': ’between’,
		'doughnut':                    ’between’,
		'line':                        ’between’,
		'pie':                         ’between’,
		'pie3d':                       ’between’,
		'pieofpiechart':               ’between’,
		'barofpiechart':               ’between’,
		'radar':                       ’between’,
		'scatter':                     ’between’,
		'surface3d':                   ’midCat’,
		'wireframesurface3d':          ’midCat’,
		'contour':                     ’midCat’,
		'wireframecontour':            ’midCat’,
		'bubble':                      ’midCat’,
		'bubble3d':                    ’midCat’);
		return m[t];
	End;
	
	Function chartValAxNumFmtFormatCode(t);
	Begin
		m := array(
		'area':                        'General',
		'areastacked':                 'General',
		'areapercentstacked':          '0%',
		'area3d':                      'General',
		'area3dstacked':               'General',
		'area3dpercentstacked':        '0%',
		'bar':                         'General',
		'barstacked':                  'General',
		'barpercentstacked':           '0%',
		'bar3dclustered':              'General',
		'bar3dstacked':                'General',
		'bar3dpercentstacked':         '0%',
		'bar3dconeclustered':          'General',
		'bar3dconestacked':            'General',
		'bar3dconepercentstacked':     '0%',
		'bar3dpyramidclustered':       'General',
		'bar3dpyramidstacked':         'General',
		'bar3dpyramidpercentstacked':  '0%',
		'bar3dcylinderclustered':      'General',
		'bar3dcylinderstacked':        'General',
		'bar3dcylinderpercentstacked': '0%',
		'col':                         'General',
		'colstacked':                  'General',
		'colpercentstacked':           '0%',
		'col3d':                       'General',
		'col3dclustered':              'General',
		'col3dstacked':                'General',
		'col3dpercentstacked':         '0%',
		'col3dcone':                   'General',
		'col3dconeclustered':          'General',
		'col3dconestacked':            'General',
		'col3dconepercentstacked':     '0%',
		'col3dpyramid':                'General',
		'col3dpyramidclustered':       'General',
		'col3dpyramidstacked':         'General',
		'col3dpyramidpercentstacked':  '0%',
		'col3dcylinder':               'General',
		'col3dcylinderclustered':      'General',
		'col3dcylinderstacked':        'General',
		'col3dcylinderpercentstacked': '0%',
		'doughnut':                    'General',
		'line':                        'General',
		'pie':                         'General',
		'pie3d':                       'General',
		'pieofpiechart':               'General',
		'barofpiechart':               'General',
		'radar':                       'General',
		'scatter':                     'General',
		'surface3d':                   'General',
		'wireframesurface3d':          'General',
		'contour':                     'General',
		'wireframecontour':            'General',
		'bubble':                      'General',
		'bubble3d':                    'General');
		return m[t];
	End;
	
	Function drawPlotAreaTxPr(TxPr);
	Begin
		TxPr.BodyPr.Rot := -60000000;
		TxPr.BodyPr.SpcFirstLastPara := true;
		TxPr.BodyPr.VertOverflow := 'ellipsis';
		TxPr.BodyPr.Vert := 'horz';
		TxPr.BodyPr.Wrap := 'square';
		TxPr.BodyPr.Anchor := 'ctr';
		TxPr.BodyPr.AnchorCtr := true;
		TxPr.P.PPr.DefRPr.Sz := 900;
		TxPr.P.PPr.DefRPr.B := false;
		TxPr.P.PPr.DefRPr.I := false;
		TxPr.P.PPr.DefRPr.U := 'none';
		TxPr.P.PPr.DefRPr.Strike := 'noStrike';
		TxPr.P.PPr.DefRPr.Kern := 1200;
		TxPr.P.PPr.DefRPr.Baseline := 0;
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.Val := 'tx1';
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.LumMod := 15000;
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.LumOff := 85000;
		TxPr.P.PPr.DefRPr.Latin.Typeface := '+mn-lt';
		TxPr.P.PPr.DefRPr.Ea.Typeface := '+mn-ea';
		TxPr.P.PPr.DefRPr.Cs.Typeface := '+mn-cs';
		TxPr.P.EndParaRPr.Lang := 'en-US';
	End;
	
	Function drawPlotAreaSpPr(SpPr);
	Begin
		SpPr.Ln.W := 9525;
		SpPr.Ln.Cap := 'flat';
		SpPr.Ln.Cmpd := 'sng';
		SpPr.Ln.Algn := 'ctr';
		SpPr.Ln.SolidFill.SchemeClr.Val := 'tx1';
		SpPr.Ln.SolidFill.SchemeClr.LumMod := 15000;
		SpPr.Ln.SolidFill.SchemeClr.LumOff := 85000;
	End;
	
	Function setChartSer(o, chart);
	Begin
		SerArr := array();
		for i:=0 to length(chart.Series)-1 do Begin
			ser := TOfficeObj('TSer');
			SerArr union= array(('name':'ser','obj':ser,'attrEx':'','nodeType':'','attrName':''));
			ser.NodeName := 'ser';
			ser.IDx := i + chart.Ord;
			ser.Ord := i + chart.Ord;
			ser.Tx.StrRef.F := chart.Series[i]['Name'];
			setSpPr(ser.SpPr, chart, i);
			setMarker(ser.Marker, chart, i);
			setDpt(ser.Dpt, chart, i);
			setDLbls(ser.DLbls, chart);
			ser.InvertIfNegative := false;
			setCat(ser.Cat, chart, i);
			setVal(ser.Val, chart, i);
			setXVal(ser.XVal, chart, i);
			setYVal(ser.YVal, chart, i);
			setBubbleSize(ser.BubbleSize, chart, i);
			setBubble3D(ser.Bubble3D, chart, i);
		End;
		o.Chart.Ser := SerArr;
	End;
	
	Function setBubble3D(Bubble3D, chart, i);
	Begin
		if chart.Type <> 'bubble3d' then return;
		Bubble3D := true;
	End;
	
	Function setBubbleSize(BubbleSize, chart, i);
	Begin
		if not (chart.Type in array('bubble', 'bubble3d')) then return;
		BubbleSize.NumRef.F := chart.Series[i]['Values'];
	End;
	
	Function setYVal(Val, chart, i);
	Begin
		if not (chart.Type in array('scatter', 'bubble', 'bubble3d')) then return;
		Val.NumRef.F := chart.Series[i]['Values'];
	End;
	
	Function setXVal(xVal, chart, i);
	Begin
		if not (chart.Type in array('scatter')) then return;
		xVal.StrRef.F := chart.Series[i]['Categories'];
	End;
	
	Function setVal(Val, chart, i);
	Begin
		if chart.Type in array('scatter', 'bubble', 'bubble3d') then return;
		Val.NumRef.F := chart.Series[i]['Values'];
	End;
	
	Function setCat(Cat, chart, i);
	Begin
		if chart.Type in array('scatter', 'bubble', 'bubble3d') then return;
		cat.StrRef.F := chart.Series[i]['Categories'];
	End;
	
	Function setDLbls(DLbls, chart);
	Begin
		if chart.Type in array('scatter','surface3d', 'wireframesurface3d', 'contour', 'wireframecontour', 'bubble', 'bubble3d') then 
			return;
		DLbls.ShowLegendKey := chart.Legend.ShowLegendKey;
		DLbls.ShowVal := chart.Plotarea.ShowVal;
		DLbls.ShowCatName := chart.Plotarea.ShowCatName;
		DLbls.ShowSerName := chart.Plotarea.ShowSerName;
		DLbls.ShowBubbleSize := chart.Plotarea.ShowBubbleSize;
		DLbls.ShowPercent := chart.Plotarea.ShowPercent;
		DLbls.ShowLeaderLines := chart.Plotarea.ShowLeaderLines;
	End;

	Function setDpt(Dpt, chart, i);
	Begin
		if chart.Type in array('pie','pie3d') then Begin
			Dpt.IDx := i;
			Dpt.Bubble3D := false;
			Dpt.SpPr.SolidFill.SchemeClr.Val := 'accent' $ (i + 1);
			Dpt.SpPr.Ln.W := 25400;
			Dpt.SpPr.Ln.Cap := 'rnd';
			Dpt.SpPr.Ln.SolidFill.SchemeClr.Val := 'lt'  $ (i + 1);
			Dpt.SpPr.Sp3D.ContourW := 25400;
			Dpt.SpPr.Sp3D.ContourClr.SchemeClr.Val := 'lt'  $ (i + 1);
		End;
	End;
	
	Function setMarker(Marker, chart, i);
	Begin
		if not (chart.Type in array('scatter', 'line')) then return;
		if chart.Type = 'scatter' then
			Marker.Symbol := 'circle';
		Marker.Size := 5;
		if ifstring(chart.Series[i]['Symbol']) then
			Marker.Symbol := chart.Series[i]['Symbol'];
		if ifint(chart.Series[i]['Size']) then
			Marker.Size := chart.Series[i]['Size'];
			
		if i < 6 then Begin
			marker.SpPr.SolidFill.SchemeClr.Val := 'accent' $ (i + 1);
			Marker.SpPr.Ln.W := 9252;
			Marker.SpPr.Ln.SolidFill.SchemeClr.Val := 'accent' $ (i + 1);
		End;
	End;
	
	Function setSppr(SpPr, chart, i);
	Begin
		if chart.Type = 'line' then Begin
			SpPr.Ln.W := 25400;
			SpPr.Ln.NoFill := ' ';
			return;
		End;
		if chart.Type = 'scatter' then Begin
			w := chart.Series[i]['LineWidth'];
			SpPr.Ln.W := 0.25 > w || w > 999 ? 25400 : 12700 * w;
			SpPr.Ln.Cap := 'rnd';
			SpPr.Ln.SolidFill.SchemeClr.Val := 'accent' $ ((chart.Ord+i)%6+1);
			return;
		End;
	End;
	
	Function getSharp(t);
	Begin
		m := array(
		'bar3dconeclustered':          'cone',
		'bar3dconestacked':            'cone',
		'bar3dconepercentstacked':     'cone',
		'bar3dpyramidclustered':       'pyramid',
		'bar3dpyramidstacked':         'pyramid',
		'bar3dpyramidpercentstacked':  'pyramid',
		'bar3dcylinderclustered':      'cylinder',
		'bar3dcylinderstacked':        'cylinder',
		'bar3dcylinderpercentstacked': 'cylinder',
		'col3dcone':                   'cone',
		'col3dconeclustered':          'cone',
		'col3dconestacked':            'cone',
		'col3dconepercentstacked':     'cone',
		'col3dpyramid':                'pyramid',
		'col3dpyramidclustered':       'pyramid',
		'col3dpyramidstacked':         'pyramid',
		'col3dpyramidpercentstacked':  'pyramid',
		'col3dcylinder':               'cylinder',
		'col3dcylinderclustered':      'cylinder',
		'col3dcylinderstacked':        'cylinder',
		'col3dcylinderpercentstacked': 'cylinder');
		return m[t];
	End;
	
	Function getChartName(t);
	Begin
		m := array(
		'area': 'areaChart',
		'areastacked': 'areaChart',
		'areapercentstacked': 'areaChart',
		'area3d': 'area3DChart',
		'area3dstacked': 'area3DChart',
		'area3dpercentstacked': 'area3DChart',
		'bar': 'barChart',
		'barstacked': 'barChart',
		'barpercentstacked': 'barChart',
		'bar3dclustered': 'bar3DChart',
		'bar3dstacked':  'bar3DChart',
		'bar3dpercentstacked': 'bar3DChart',
		'bar3dconeclustered': 'bar3DChart',
		'bar3dconestacked': 'bar3DChart',
		'bar3dconepercentstacked': 'bar3DChart',
		'bar3dpyramidclustered': 'bar3DChart',
		'bar3dpyramidstacked': 'bar3DChart',
		'bar3dpyramidpercentstacked': 'bar3DChart',
		'bar3dcylinderclustered': 'bar3DChart',
		'bar3dcylinderstacked': 'bar3DChart',
		'bar3dcylinderpercentstacked': 'bar3DChart',
		'col': 'barChart',
		'colstacked': 'barChart',
		'colpercentstacked': 'barChart',
		'col3d': 'bar3DChart',
		'col3dclustered': 'bar3DChart',
		'col3dstacked': 'bar3DChart',
		'col3dpercentstacked': 'bar3DChart',
		'col3dcone': 'bar3DChart',
		'col3dconeclustered': 'bar3DChart',
		'col3dconestacked': 'bar3DChart',
		'col3dconepercentstacked': 'bar3DChart',
		'col3dpyramid': 'bar3DChart',
		'col3dpyramidclustered': 'bar3DChart',
		'col3dpyramidstacked': 'bar3DChart',
		'col3dpyramidpercentstacked': 'bar3DChart',
		'col3dcylinder': 'bar3DChart',
		'col3dcylinderclustered': 'bar3DChart',
		'col3dcylinderstacked': 'bar3DChart',
		'col3dcylinderpercentstacked': 'bar3DChart',
		'bubble': 'bubbleChart',
		'bubble3D': 'bubbleChart');
		return m[t];
	End;
	
	Function getVaryColors(t);
	Begin
		m := array(
		'barstacked':        100,
		'barpercentstacked': 100,
		'colstacked':        100,
		'colpercentstacked': 100
		);
		return m[t];
	End;
	
	Function getGrouping(t);
	Begin
		m := array(
		'area':                        'standard',
		'areastacked':                 'stacked',
		'areapercentstacked':          'percentstacked',
		'area3d':                      'standard',
		'area3dstacked':               'stacked',
		'area3dpercentstacked':        'percentstacked',
		'bar':                         'clustered',
		'barstacked':                  'stacked',
		'barpercentstacked':           'percentstacked',
		'bar3dclustered':              'clustered',
		'bar3dstacked':                'stacked',
		'bar3dpercentstacked':         'percentstacked',
		'bar3dconeclustered':          'clustered',
		'bar3dconestacked':            'stacked',
		'bar3dconepercentstacked':     'percentstacked',
		'bar3dpyramidclustered':       'clustered',
		'bar3dpyramidstacked':         'stacked',
		'bar3dpyramidpercentstacked':  'percentstacked',
		'bar3dcylinderclustered':      'clustered',
		'bar3dcylinderstacked':        'stacked',
		'bar3dcylinderpercentstacked': 'percentstacked',
		'col':                         'clustered',
		'colstacked':                  'stacked',
		'colpercentstacked':           'percentstacked',
		'col3d':                       'standard',
		'col3dclustered':              'clustered',
		'col3dstacked':                'stacked',
		'col3dpercentstacked':         'percentstacked',
		'col3dcone':                   'standard',
		'col3dconeclustered':          'clustered',
		'col3dconestacked':            'stacked',
		'col3dconepercentstacked':     'percentstacked',
		'col3dpyramid':                'standard',
		'col3dpyramidclustered':       'clustered',
		'col3dpyramidstacked':         'stacked',
		'col3dpyramidpercentstacked':  'percentstacked',
		'col3dcylinder':               'standard',
		'col3dcylinderclustered':      'clustered',
		'col3dcylinderstacked':        'stacked',
		'col3dcylinderpercentstacked': 'percentstacked',
		'line':                        'standard');
		return m[t];
	End;
	
	Function getBarDir(t);
	Begin
		m := array(
		'bar':                         'bar',
		'barstacked':                  'bar',
		'barpercentstacked':           'bar',
		'bar3dclustered':              'bar',
		'bar3dstacked':                'bar',
		'bar3dpercentstacked':         'bar',
		'bar3dconeclustered':          'bar',
		'bar3dconestacked':            'bar',
		'bar3dconepercentstacked':     'bar',
		'bar3dpyramidclustered':       'bar',
		'bar3dpyramidstacked':         'bar',
		'bar3dpyramidpercentstacked':  'bar',
		'bar3dcylinderclustered':      'bar',
		'bar3dcylinderstacked':        'bar',
		'bar3dcylinderpercentstacked': 'bar',
		'col':                         'col',
		'colstacked':                  'col',
		'colpercentstacked':           'col',
		'col3d':                       'col',
		'col3dclustered':              'col',
		'col3dstacked':                'col',
		'col3dpercentstacked':         'col',
		'col3dcone':                   'col',
		'col3dconestacked':            'col',
		'col3dconeclustered':          'col',
		'col3dconepercentstacked':     'col',
		'col3dpyramid':                'col',
		'col3dpyramidclustered':       'col',
		'col3dpyramidstacked':         'col',
		'col3dpyramidpercentstacked':  'col',
		'col3dcylinder':               'col',
		'col3dcylinderclustered':      'col',
		'col3dcylinderstacked':        'col',
		'col3dcylinderpercentstacked': 'col',
		'line':                        'standard');
		return m[t];
	End;

	sheetName_:string; //sheet名称
	sheetFileName_; //xl/worksheets/sheetN.xml
	xlChartFileName_:string;
	xlDrawingFileName_:string; //'xl/drawings/drawingN.xml';
	drawingXmlObj_;
	drawingRID_:integer;
	chartId_;
	chartRid_;
	excel_;//TSExcelFile对象
End;