Browse Source

Fix Issue #59 :Multiply rows and columns can be passed to

Chart::addSeries() now
master
Debao Zhang 10 years ago
parent
commit
9e33ff2c79
  1. 41
      examples/xlsx/chart/main.cpp
  2. 120
      src/xlsx/xlsxchart.cpp
  3. 7
      src/xlsx/xlsxchart_p.h

41
examples/xlsx/chart/main.cpp

@ -9,50 +9,63 @@ int main()
{ {
//![0] //![0]
Document xlsx; Document xlsx;
for (int i=1; i<10; ++i) for (int i=1; i<10; ++i) {
xlsx.write(i, 1, i*i); xlsx.write(i, 1, i*i*i); //A1:A9
xlsx.write(i, 2, i*i); //B1:B9
xlsx.write(i, 3, i*i-1); //C1:C9
}
//![0] //![0]
//![1] //![1]
Chart *pieChart = xlsx.insertChart(3, 3, QSize(300, 300)); Chart *pieChart = xlsx.insertChart(3, 3, QSize(300, 300));
pieChart->setChartType(Chart::CT_Pie); pieChart->setChartType(Chart::CT_Pie);
pieChart->addSeries(CellRange("A1:A9")); pieChart->addSeries(CellRange("A1:A9"));
pieChart->addSeries(CellRange("B1:B9"));
pieChart->addSeries(CellRange("C1:C9"));
Chart *pie3DChart = xlsx.insertChart(3, 7, QSize(300, 300)); Chart *pie3DChart = xlsx.insertChart(3, 9, QSize(300, 300));
pie3DChart->setChartType(Chart::CT_Pie3D); pie3DChart->setChartType(Chart::CT_Pie3D);
pie3DChart->addSeries(CellRange("A1:A9")); pie3DChart->addSeries(CellRange("A1:C9"));
Chart *barChart = xlsx.insertChart(23, 3, QSize(300, 300)); Chart *barChart = xlsx.insertChart(23, 3, QSize(300, 300));
barChart->setChartType(Chart::CT_Bar); barChart->setChartType(Chart::CT_Bar);
barChart->addSeries(CellRange("A1:A9")); barChart->addSeries(CellRange("A1:C9"));
Chart *bar3DChart = xlsx.insertChart(23, 7, QSize(300, 300)); Chart *bar3DChart = xlsx.insertChart(23, 9, QSize(300, 300));
bar3DChart->setChartType(Chart::CT_Bar3D); bar3DChart->setChartType(Chart::CT_Bar3D);
bar3DChart->addSeries(CellRange("A1:A9")); bar3DChart->addSeries(CellRange("A1:C9"));
Chart *lineChart = xlsx.insertChart(43, 3, QSize(300, 300)); Chart *lineChart = xlsx.insertChart(43, 3, QSize(300, 300));
lineChart->setChartType(Chart::CT_Line); lineChart->setChartType(Chart::CT_Line);
lineChart->addSeries(CellRange("A1:A9")); lineChart->addSeries(CellRange("A1:C9"));
Chart *line3DChart = xlsx.insertChart(43, 7, QSize(300, 300)); Chart *line3DChart = xlsx.insertChart(43, 9, QSize(300, 300));
line3DChart->setChartType(Chart::CT_Line3D); line3DChart->setChartType(Chart::CT_Line3D);
line3DChart->addSeries(CellRange("A1:A9")); line3DChart->addSeries(CellRange("A1:C9"));
Chart *areaChart = xlsx.insertChart(63, 3, QSize(300, 300)); Chart *areaChart = xlsx.insertChart(63, 3, QSize(300, 300));
areaChart->setChartType(Chart::CT_Area); areaChart->setChartType(Chart::CT_Area);
areaChart->addSeries(CellRange("A1:A9")); areaChart->addSeries(CellRange("A1:C9"));
Chart *area3DChart = xlsx.insertChart(63, 7, QSize(300, 300)); Chart *area3DChart = xlsx.insertChart(63, 9, QSize(300, 300));
area3DChart->setChartType(Chart::CT_Area3D); area3DChart->setChartType(Chart::CT_Area3D);
area3DChart->addSeries(CellRange("A1:A9")); area3DChart->addSeries(CellRange("A1:C9"));
Chart *scatterChart = xlsx.insertChart(83, 3, QSize(300, 300)); Chart *scatterChart = xlsx.insertChart(83, 3, QSize(300, 300));
scatterChart->setChartType(Chart::CT_Scatter); scatterChart->setChartType(Chart::CT_Scatter);
//Will generate three lines.
scatterChart->addSeries(CellRange("A1:A9")); scatterChart->addSeries(CellRange("A1:A9"));
scatterChart->addSeries(CellRange("B1:B9"));
scatterChart->addSeries(CellRange("C1:C9"));
Chart *scatterChart_2 = xlsx.insertChart(83, 9, QSize(300, 300));
scatterChart_2->setChartType(Chart::CT_Scatter);
//Will generate two lines.
scatterChart_2->addSeries(CellRange("A1:C9"));
Chart *doughnutChart = xlsx.insertChart(103, 3, QSize(300, 300)); Chart *doughnutChart = xlsx.insertChart(103, 3, QSize(300, 300));
doughnutChart->setChartType(Chart::CT_Doughnut); doughnutChart->setChartType(Chart::CT_Doughnut);
doughnutChart->addSeries(CellRange("A1:A9")); doughnutChart->addSeries(CellRange("A1:C9"));
//![1] //![1]
//![2] //![2]

120
src/xlsx/xlsxchart.cpp

@ -96,20 +96,55 @@ Chart::~Chart()
void Chart::addSeries(const CellRange &range, AbstractSheet *sheet) void Chart::addSeries(const CellRange &range, AbstractSheet *sheet)
{ {
Q_D(Chart); Q_D(Chart);
if (!range.isValid())
return;
if (sheet && sheet->sheetType() != AbstractSheet::ST_WorkSheet) if (sheet && sheet->sheetType() != AbstractSheet::ST_WorkSheet)
return; return;
if (!sheet && d->sheet->sheetType() != AbstractSheet::ST_WorkSheet) if (!sheet && d->sheet->sheetType() != AbstractSheet::ST_WorkSheet)
return; return;
QString serRef = sheet ? sheet->sheetName() : d->sheet->sheetName(); QString sheetName = sheet ? sheet->sheetName() : d->sheet->sheetName();
if (range.columnCount() == 1 || range.rowCount() == 1) {
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
series->numberDataSource_numRef = sheetName + QLatin1String("!") + range.toString(true, true);
d->seriesList.append(series);
} else if (range.columnCount() < range.rowCount()) {
//Column based series
int firstDataColumn = range.firstColumn();
QString axDataSouruce_numRef;
if (d->chartType == CT_Scatter || d->chartType == CT_Bubble) {
firstDataColumn += 1;
CellRange subRange(range.firstRow(), range.firstColumn(), range.lastRow(), range.firstColumn());
axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
}
serRef += QLatin1String("!"); for (int col=firstDataColumn; col<=range.lastColumn(); ++col) {
serRef += range.toString(true, true); CellRange subRange(range.firstRow(), col, range.lastRow(), col);
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
series->axDataSource_numRef = axDataSouruce_numRef;
series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
d->seriesList.append(series);
}
XlsxSeries *series = new XlsxSeries; } else {
series->numRef = serRef; //Row based series
int firstDataRow = range.firstRow();
QString axDataSouruce_numRef;
if (d->chartType == CT_Scatter || d->chartType == CT_Bubble) {
firstDataRow += 1;
CellRange subRange(range.firstRow(), range.firstColumn(), range.firstRow(), range.lastColumn());
axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
}
d->seriesList.append(QSharedPointer<XlsxSeries>(series)); for (int row=firstDataRow; row<=range.lastRow(); ++row) {
CellRange subRange(row, range.firstColumn(), row, range.lastColumn());
QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
series->axDataSource_numRef = axDataSouruce_numRef;
series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
d->seriesList.append(series);
}
}
} }
/*! /*!
@ -253,23 +288,57 @@ bool ChartPrivate::loadXmlSer(QXmlStreamReader &reader)
{ {
Q_ASSERT(reader.name() == QLatin1String("ser")); Q_ASSERT(reader.name() == QLatin1String("ser"));
while (!reader.atEnd()) { QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
seriesList.append(series);
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == QLatin1String("ser"))) {
if (reader.readNextStartElement()) {
QStringRef name = reader.name();
if (name == QLatin1String("cat") || name == QLatin1String("xVal")) {
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == name)) {
if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("numRef"))
series->axDataSource_numRef = loadXmlNumRef(reader);
}
}
} else if (name == QLatin1String("val") || name == QLatin1String("yVal")) {
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == name)) {
if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("numRef"))
series->numberDataSource_numRef = loadXmlNumRef(reader);
}
}
} else if (name == QLatin1String("extLst")) {
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == name)) {
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("f")) {
XlsxSeries *series = new XlsxSeries;
series->numRef = reader.readElementText();
seriesList.append(QSharedPointer<XlsxSeries>(series));
} }
} else if (reader.tokenType() == QXmlStreamReader::EndElement }
&& reader.name() == QLatin1String("ser")) {
break;
} }
} }
return true; return true;
} }
QString ChartPrivate::loadXmlNumRef(QXmlStreamReader &reader)
{
Q_ASSERT(reader.name() == QLatin1String("numRef"));
while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == QLatin1String("numRef"))) {
if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("f"))
return reader.readElementText();
}
}
return QString();
}
void ChartPrivate::saveXmlChart(QXmlStreamWriter &writer) const void ChartPrivate::saveXmlChart(QXmlStreamWriter &writer) const
{ {
writer.writeStartElement(QStringLiteral("c:chart")); writer.writeStartElement(QStringLiteral("c:chart"));
@ -459,14 +528,29 @@ void ChartPrivate::saveXmlSer(QXmlStreamWriter &writer, XlsxSeries *ser, int id)
writer.writeAttribute(QStringLiteral("val"), QString::number(id)); writer.writeAttribute(QStringLiteral("val"), QString::number(id));
writer.writeEmptyElement(QStringLiteral("c:order")); writer.writeEmptyElement(QStringLiteral("c:order"));
writer.writeAttribute(QStringLiteral("val"), QString::number(id)); writer.writeAttribute(QStringLiteral("val"), QString::number(id));
if (chartType == Chart::CT_Scatter)
if (!ser->axDataSource_numRef.isEmpty()) {
if (chartType == Chart::CT_Scatter || chartType == Chart::CT_Bubble)
writer.writeStartElement(QStringLiteral("c:xVal"));
else
writer.writeStartElement(QStringLiteral("c:cat"));
writer.writeStartElement(QStringLiteral("c:numRef"));
writer.writeTextElement(QStringLiteral("c:f"), ser->axDataSource_numRef);
writer.writeEndElement();//c:numRef
writer.writeEndElement();//c:cat or c:xVal
}
if (!ser->numberDataSource_numRef.isEmpty()) {
if (chartType == Chart::CT_Scatter || chartType == Chart::CT_Bubble)
writer.writeStartElement(QStringLiteral("c:yVal")); writer.writeStartElement(QStringLiteral("c:yVal"));
else else
writer.writeStartElement(QStringLiteral("c:val")); writer.writeStartElement(QStringLiteral("c:val"));
writer.writeStartElement(QStringLiteral("c:numRef")); writer.writeStartElement(QStringLiteral("c:numRef"));
writer.writeTextElement(QStringLiteral("c:f"), ser->numRef); writer.writeTextElement(QStringLiteral("c:f"), ser->numberDataSource_numRef);
writer.writeEndElement();//c:numRef writer.writeEndElement();//c:numRef
writer.writeEndElement();//c:val writer.writeEndElement();//c:val or c:yVal
}
writer.writeEndElement();//c:ser writer.writeEndElement();//c:ser
} }

7
src/xlsx/xlsxchart_p.h

@ -50,9 +50,9 @@ namespace QXlsx {
class XlsxSeries class XlsxSeries
{ {
public: public:
//At present, we care about number cell ranges only!
QString numRef;// For scatterChart, means y values QString numberDataSource_numRef; //yval, val
QString numRef_x; QString axDataSource_numRef; //xval, cat
}; };
class XlsxAxis class XlsxAxis
@ -99,6 +99,7 @@ public:
bool loadXmlPlotArea(QXmlStreamReader &reader); bool loadXmlPlotArea(QXmlStreamReader &reader);
bool loadXmlXxxChart(QXmlStreamReader &reader); bool loadXmlXxxChart(QXmlStreamReader &reader);
bool loadXmlSer(QXmlStreamReader &reader); bool loadXmlSer(QXmlStreamReader &reader);
QString loadXmlNumRef(QXmlStreamReader &reader);
bool loadXmlAxis(QXmlStreamReader &reader); bool loadXmlAxis(QXmlStreamReader &reader);
void saveXmlChart(QXmlStreamWriter &writer) const; void saveXmlChart(QXmlStreamWriter &writer) const;

Loading…
Cancel
Save