Exemplo n.º 1
0
void ClusterView::customEvent(QCustomEvent* event){
 if(event->type() == QEvent::User + 700){
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  
  ComputeEvent* computeEvent = (ComputeEvent*) event;
  //Get the polygon
  QPointArray polygon = computeEvent->polygon();
  QRegion selectionArea;
  QPointArray reviewPolygon;
  long Xdimension = 0;
  long Ydimension = 0;

   //The QRegion uses rectangles to define its area and the number of rectangles
   //increases with the height of the region (y axis). The more rectangles the longer
   //the search of one point in the region will take. With a dimension like the time
   //the height has an order of the millon (at least 5 going to 80 or more) given a huge amount
   //of rectangles. A way of speeding the search of points is to reduce the number of rectangles.
   //To do so, if the y dimension is the time, x and y axis are inverted.
   //Caution: in Qt graphical coordinate system, the Y axis is inverted (increasing downwards),
   //thus a point (x,y) is drawn as (x,-y), before creating the region the points are reset to there raw value (x,y).
     
  if(view.ordinateDimension() != timeDimension){
    for(uint i = 0; i< polygon.size();++i){
     reviewPolygon.putPoints(i, 1,polygon.point(i).x(),-polygon.point(i).y());
     Xdimension = dimensionX;
     Ydimension = dimensionY;    
    }
  }
  else{    
    for(uint i = 0; i< polygon.size();++i){
     reviewPolygon.putPoints(i, 1,-polygon.point(i).y(),polygon.point(i).x());

     Xdimension = dimensionY;
     Ydimension = dimensionX;         
   }
  }
  //Create a QRegion with the new selection area in order to use the research facilities offer by a QRegion.  
  selectionArea = QRegion(reviewPolygon);
  if(!selectionArea.isNull()){
    //Call any appropriate method
    switch(mode){
     case DELETE_NOISE:
        doc.deleteNoise(selectionArea,view.clusters(),Xdimension,Ydimension);        
        break;
     case DELETE_ARTEFACT:
       doc.deleteArtifact(selectionArea,view.clusters(),Xdimension,Ydimension);
       break;
     case NEW_CLUSTER:
       doc.createNewCluster(selectionArea,view.clusters(),Xdimension,Ydimension);
       break;
     case NEW_CLUSTERS:
        doc.createNewClusters(selectionArea,view.clusters(),Xdimension,Ydimension);
       break;
     case ZOOM:
       break; //nothing to do   
    }
  }
  QApplication::restoreOverrideCursor(); 
 }
}
Exemplo n.º 2
0
QPoint Reversi::ai(const int player)
{
	const int choices[8][8] = {
		{100,	-100,	50,	30,	30,	50,	-100,	100,},
		{-100,	-100,	-50,	-50,	-50,	-50,	-100,	-100,},
		{50,	-50,	10,	10,	10,	10,	-50,	50,},
		{30,	-50,	10,	0,	0,	10,	-50,	30,},
		{30,	-50,	10,	0,	0,	10,	-50,	30,},
		{50,	-50,	10,	10,	10,	10,	-50,	50,},
		{-100,	-100,	-50,	-50,	-50,	-50,	-100,	-100,},
		{100,	-100,	50,	30,	30,	50,	-100,	100,},
	};
	QPointArray spaces = availableSpaces(player);
	if (spaces.size() == 0)
		return BoardGame::ai(player);
	int values[spaces.size()];
	for (unsigned int i = 0; i < spaces.size(); i++) {
		QPoint p(spaces[i]);
		values[i] = choices[p.y()][p.x()] + reversible(p, player) * 5;
	}
	int max = 0;
	for (unsigned int i = 0; i < spaces.size(); i++)
		if (values[i] > values[max])
			max = i;
	QList<int> equals;
	equals.setAutoDelete(true);
	for (unsigned int i = 0; i < spaces.size(); i++)
		if (values[i] == values[max])
			equals.append(new int(i));
	return spaces[*equals.at(rand() % equals.count())];
}
Exemplo n.º 3
0
QRegion::QRegion( const QPointArray &a, bool winding )
{
    data = new QRegionData;
    Q_CHECK_PTR( data );
    data->hgt = 0;
    data->is_null = FALSE;
    QRect r = a.boundingRect();
    if ( a.isEmpty() || r.isEmpty() ) {
	data->rgn = 0;
    } else {
        HPS hps = qt_display_ps();
        POINTL *pts = new POINTL[ a.size() ]; 
        for ( uint i = 0; i < a.size(); ++ i ) {
            pts[i].x = a[i].x();
            pts[i].y = - (a[i].y() + 1);
        }
        // GpiCreatePolygonRegion() is bogus and always starts a poligon from
        // the current position. Make the last point the current one and reduce
        // the number of points by one.
        GpiMove( hps, &pts[ a.size() - 1 ] );
        POLYGON poly = { a.size() - 1, pts };
        ULONG opts = winding ? POLYGON_WINDING : POLYGON_ALTERNATE;
        data->rgn = GpiCreatePolygonRegion( hps, 1, &poly, opts );
        delete[] pts;
    }
}
Exemplo n.º 4
0
QRegion::QRegion( const QRect &r, RegionType t )
{
    data = new QRegionData;
    Q_CHECK_PTR( data );
    data->hgt = 0;
    data->is_null = FALSE;
    if ( r.isEmpty() ) {
	data->rgn = 0;
    } else {
        HPS hps = qt_display_ps();
	if ( t == Rectangle ) {			// rectangular region
            RECTL rcl = { r.left(), -(r.bottom()+1), r.right()+1, -r.top() };
            data->rgn = GpiCreateRegion( hps, 1, &rcl );
	} else if ( t == Ellipse ) {		// elliptic region
            // if the width or height of the ellipse is odd, GPI always
            // converts it to a nearest even value, which is obviously stupid
            // (see also QPainter::drawArcInternal()). So, we don't use
            // GpiCreateEllipticRegion(), but create an array of points to
            // call GpiCreatePolygonRegion() instead.
            QPointArray a;
            a.makeArc( r.x(), r.y(), r.width(), r.height(), 0, 360 * 16 );
            for ( uint i = 0; i < a.size(); ++ i )
                a[i].ry() = -(a[i].y() + 1);
            // GpiCreatePolygonRegion() is bogus and always starts a poligon from
            // the current position. Make the last point the current one and reduce
            // the number of points by one.
            GpiMove( hps, (PPOINTL) &a[ a.size() - 1 ] );
            POLYGON poly = { a.size() - 1, (PPOINTL) a.data() };
            data->rgn = GpiCreatePolygonRegion( hps, 1, &poly, POLYGON_ALTERNATE );
	}
    }
}
Exemplo n.º 5
0
QRegion::QRegion( const QPointArray &a, bool winding )
{
    data = new QRegionData;
    CHECK_PTR( data );
    data->is_null = FALSE;
    data->rgn = XPolygonRegion( (XPoint*)a.data(), a.size(),
				winding ? WindingRule : EvenOddRule );
}
Exemplo n.º 6
0
QPointArray Reversi::availableSpaces(const int player) const
{
	QPointArray spaces;
	for (int r = 0; r < size().height(); r++)
		for (int c = 0; c < size().width(); c++)
			if (available(QPoint(c, r), player))
				spaces.putPoints(spaces.size(), 1, c, r);
	return spaces;
}
Exemplo n.º 7
0
QPointArray QWMatrix::map( const QPointArray &a ) const
{
    QPointArray result = a.copy();
    int x, y;
    for ( int i=0; i<(int)result.size(); i++ ) {
	result.point( i, &x, &y );
	map( x, y, &x, &y );
	result.setPoint( i, x, y );
    }
    return result;
}
Exemplo n.º 8
0
void QwtCurve::closePolyline(const QwtDiMap &xMap, const QwtDiMap &yMap,
    QPointArray &pa) const
{
    const int sz = pa.size();
    if ( sz < 2 )
        return;

    pa.resize(sz + 2);

    if ( d_options & QwtCurve::Xfy )
    {
        pa.setPoint(sz,
            xMap.transform(d_ref), pa.point(sz - 1).y());
        pa.setPoint(sz + 1,
            xMap.transform(d_ref), pa.point(0).y());
    }
    else
    {
        pa.setPoint(sz,
            pa.point(sz - 1).x(), yMap.transform(d_ref));
        pa.setPoint(pa.size() - 1,
            pa.point(0).x(), yMap.transform(d_ref));
    }
}
Exemplo n.º 9
0
void KIconEditGrid::drawPointArray(QPointArray a, DrawAction action)
{
  QRect rect = a.boundingRect();
  bool update = false;

  int s = a.size(); //((rect.size().width()) * (rect.size().height()));
  for(int i = 0; i < s; i++)
  {
    int x = a[i].x();
    int y = a[i].y();
    //if(img->valid(x, y) && !QSize(x, y).isNull() && rect.contains(QPoint(x, y)))
    if(img->valid(x, y) && rect.contains(QPoint(x, y)))
    {
      //debug("x: %d - y: %d", x, y);
      switch( action )
      {
        case Draw:
        {
          *((uint*)img->scanLine(y) + x) = currentcolor; //colors[cell]|OPAQUE;
          int cell = y * numCols() + x;
          setColor( cell, currentcolor, false );
          modified = true;
          update = true;
          //updateCell( y, x, FALSE );
          break;
        }
        case Mark:
        case UnMark:
          repaint(x*cellsize,y*cellsize, cellsize, cellsize, false);
          //updateCell( y, x, true );
          break;
        default:
          break;
      }
    }
  }
  if(update)
  {
    updateColors();
    repaint(rect.x()*cellSize()-1, rect.y()*cellSize()-1,
        rect.width()*cellSize()+1, rect.height()*cellSize()+1, false);
    pntarray.resize(0);
  }

}
	void KviCanvasView::dragPolygon(KviCanvasPolygon * it,const QPoint &p)
	{
		switch(m_dragMode)
		{
			case All:
				it->move(p.x() - m_dragBegin.x(),p.y() - m_dragBegin.y());
			break;
			case SinglePoint:
			{
				QPointArray pnt = it->internalPoints();
				pnt.setPoint(m_dragPointIndex,(int)((p.x() - it->x()) / it->scaleFactor()),(int)((p.y() - it->y()) / it->scaleFactor()));
				it->setInternalPoints(pnt);
			}
			break;
			case Scale:
			{
				double dDistance = ssm_hypot(p.x() - it->x(),p.y() - it->y());
				double dOriginal = ssm_hypot(m_dragBegin.x(),m_dragBegin.y());
				if(dOriginal < 1)dOriginal = 1;
				if(dDistance < 0.1)dDistance = 0.1;
				it->setScaleFactor(m_dragScaleFactor * dDistance / dOriginal);
			}
			break;
			case Rotate:
			{
				QPoint act((int)(p.x() - it->x()),(int)(p.y() - it->y()));
				double dAngle = ssm_2d_rotationAngle(m_dragBegin.x(),m_dragBegin.y(),act.x(),act.y());
	//			qDebug("%d,%d %d,%d %f",m_dragBegin.x(),m_dragBegin.y(),act.x(),act.y(),dAngle);
				QPointArray thePoints = m_dragPointArray.copy();
				for(unsigned int i=0;i<thePoints.size();i++)
				{
					QPoint tmp = thePoints.point(i);
					double dx = tmp.x();
					double dy = tmp.y();
					ssm_2d_rotate(dx,dy,dAngle);
					thePoints.setPoint(i,(int)dx,(int)dy);
				}
				it->setInternalPoints(thePoints);
			}
			break;
			default:
			break;
		}
		canvas()->update();
	}
	void KviCanvasView::beginDragPolygon(KviCanvasPolygon * it,const QPoint &p,bool bShift,bool bCtrl)
	{
		m_dragBegin = QPoint((int)(p.x() - it->x()),(int)(p.y() - it->y()));

		QPointArray pa = it->areaPoints();

		for(unsigned int i=0;i<pa.size();i++)
		{
			QPoint pnt = pa.point(i);
			double dX = pnt.x() - p.x();
			double dY = pnt.y() - p.y();
			double dHypot = sqrt((dX * dX) + (dY * dY));
			if(dHypot < 3.0)
			{
				// We're dragging a point
				m_dragMode = SinglePoint;
				m_dragPointIndex = i;
				setCursor(crossCursor);
				return;
			}
		}

		if(bShift)
		{
			m_dragMode = Scale;
			m_dragScaleFactor = it->scaleFactor();
			setCursor(sizeAllCursor);
			return;
		}

		if(bCtrl)
		{
			m_dragMode = Rotate;
			m_dragPointArray = it->internalPoints();
	//		qDebug("Here");
			setCursor(sizeHorCursor);
			return;
		}

		m_dragMode = All;
		setCursor(pointingHandCursor);
	}
Exemplo n.º 12
0
QRegion::QRegion( const QRect &r, RegionType t )
{
    QRect rr = r.normalize();
    data = new QRegionData;
    CHECK_PTR( data );
    data->is_null = FALSE;
    if ( t == Rectangle ) {			// rectangular region
	data->rgn = XCreateRegion();
	XRectangle xr;
	xr.x = rr.x();
	xr.y = rr.y();
	xr.width  = rr.width();
	xr.height = rr.height();
	XUnionRectWithRegion( &xr, data->rgn, data->rgn );
    } else if ( t == Ellipse ) {		// elliptic region
	QPointArray a;
	a.makeEllipse( rr.x(), rr.y(), rr.width(), rr.height() );
	data->rgn = XPolygonRegion( (XPoint*)a.data(), a.size(), EvenOddRule );
    }
}
Exemplo n.º 13
0
void KDChartLinesPainter::specificPaintData( QPainter* painter,
                                             const QRect& /*ourClipRect*/,
                                             KDChartTableDataBase* data,
                                             KDChartDataRegionList* regions,
                                             const KDChartAxisParams* ordinatePara,
                                             bool /*bNormalMode*/,
                                             uint chart,
                                             double logWidth,
                                             double /*areaWidthP1000*/,
                                             double logHeight,
                                             double axisYOffset,
                                             double minColumnValue,
                                             double maxColumnValue,
                                             double columnValueDistance,
                                             uint /*chartDatasetStart*/,
                                             uint /*chartDatasetEnd*/,
                                             uint datasetStart,
                                             uint datasetEnd )
{
    if( !data ) return;


    abscissaInfos ai;
    ai.bCenterThePoints = mCenterThePoints;
    calculateAbscissaInfos( *params(), *data,
                            datasetStart, datasetEnd,
                            logWidth, _dataRect,
                            ai );
    mCenterThePoints = ai.bCenterThePoints;

    bool bOrdinateDecreasing = ordinatePara
        ? ordinatePara->axisValuesDecreasing()
        : false;
    bool bOrdinateIsLogarithmic
        = ordinatePara
        ? (KDChartAxisParams::AxisCalcLogarithmic == ordinatePara->axisCalcMode())
        : false;

    //const double ordinatePixelsPerUnit = logHeight / columnValueDistance;
    const double ordinatePixelsPerUnit
        = (    ordinatePara
               && (0.0 != ordinatePara->trueAxisDeltaPixels())
               && (0.0 != ordinatePara->trueAxisDelta()))
        ? ordinatePara->trueAxisDeltaPixels() / ordinatePara->trueAxisDelta()
        : logHeight / columnValueDistance;;
    //qDebug("ordinatePixelsPerUnit: %f",ordinatePixelsPerUnit);


    const bool showThreeDLines = !mIsArea && params()->threeDLines();

    enum { Normal, Stacked, Percent } mode = Normal;
    if (    (    ( mChartType                   == KDChartParams::Line )
                 && ( params()->lineChartSubType() == KDChartParams::LineNormal ) )
            || (    ( mChartType                   == KDChartParams::Area )
                    && ( params()->areaChartSubType() == KDChartParams::AreaNormal ) ) )
        mode = Normal;
    else if (    (    ( mChartType                   == KDChartParams::Line )
                      && ( params()->lineChartSubType() == KDChartParams::LineStacked ) )
                 || (    ( mChartType                   == KDChartParams::Area )
                         && ( params()->areaChartSubType() == KDChartParams::AreaStacked ) ) )
        mode = Stacked;
    else if (    (    ( mChartType                   == KDChartParams::Line )
                      && ( params()->lineChartSubType() == KDChartParams::LinePercent ) )
                 || (    ( mChartType                   == KDChartParams::Area )
                         && ( params()->areaChartSubType() == KDChartParams::AreaPercent ) ) )
        mode = Percent;
    else
        qDebug( "Internal error in KDChartLinesPainter::paintDataInternal(): Unknown subtype" );


    QMap < int, double > currentValueSums;
    if ( mode == Stacked || mode == Percent ) {
        // this array is only used for stacked and percent lines, no need
        // to waste time initializing it for normal types
        for ( int value = 0; value < ai.numValues; ++value )
            currentValueSums[ value ] = 0.0;
    }
    QMap < int, double > totalValueSums;

    // compute the position of the 0 axis
    double zeroXAxisI;
    if ( mode == Percent ) {
        if ( minColumnValue == 0.0 )
            zeroXAxisI = logHeight + axisYOffset;
        else if( maxColumnValue == 0.0 )
            zeroXAxisI = _dataRect.y() + axisYOffset;
        else
            zeroXAxisI = logHeight / 2.0 + _dataRect.y();
    } else
        zeroXAxisI = ordinatePara->axisZeroLineStartY() - _dataRect.y();


    // compute how to shift of the points in case we want them in the
    // middle of their respective columns
    int xShift = mCenterThePoints ? static_cast < int > ( ai.pointDist * 0.5 ) : 0;


    // calculate all points' positions
    // ===============================
    int arrayNumDatasets = 0;
    int arrayNumValues   = ai.bAbscissaHasTrueAxisDtValues
        ? data->cols()
        : ai.numValues;
    int dataset;
    for( dataset = datasetEnd;
         ( dataset >= static_cast < int > ( datasetStart ) && dataset >= 0 );
         --dataset )
        ++arrayNumDatasets;
#if COMPAT_QT_VERSION >= 0x030000
    QValueVector<MyPoint> allPoints(
#else
    QArray<MyPoint> allPoints(
#endif
                              arrayNumDatasets * arrayNumValues );
                                    
    KDChartPropertySet curPropSet;
    int curPropSetId = KDChartPropertySet::UndefinedID;
                                    
    for( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {
                                        
        int prevPointX = -1;
        int prevPointY = -1;
                                        
        const KDChartParams::LineMarkerStyle
            defaultMarkerStyle = params()->lineMarkerStyle( dataset );
        const QPen default2DPen(   params()->lineColor().isValid()
                                   ? params()->lineColor()
                                   : params()->dataColor( dataset ),
                                   params()->lineWidth(),
                                   params()->lineStyle( dataset ) );

        if( ai.bAbscissaHasTrueAxisDtValues )
            ai.numValues = data->cols();

        QVariant vValY;
        QVariant vValX;
        int cellPropID;
        for( int value = 0; value < ai.numValues; ++value ) {
            //if ( mode == Percent )
            //    valueTotal = data->colAbsSum( value );
            double valueTotal = 0.0; // Will only be used for Percent
            if( mode == Percent ) {
                valueTotal = 0.0;
                // iterate over datasets of this axis only:
                for ( uint dataset2  = datasetStart;
                      dataset2 <= datasetEnd;
                      ++dataset2 ) {
                    if( data->cellCoord( dataset2, value, vValY, 1 ) &&
                        QVariant::Double == vValY.type() )
                        valueTotal += vValY.toDouble();
                }
            }

            if( data->cellContent( dataset, value, vValY, vValX, cellPropID ) &&
                QVariant::Double == vValY.type() &&
                ( !ai.bCellsHaveSeveralCoordinates || QVariant::Invalid != vValX.type() ) ){
                //qDebug("a. cellPropID: %i",cellPropID);

                // calculate Ordinate axis value
                // -----------------------------
                double cellValue = vValY.toDouble();
                double drawValue = 0.0;
                // PENDING(kalle) This does not work for AreaPercent yet
                if ( mode == Stacked )
                    drawValue = ( cellValue + currentValueSums[ value ] ) * ordinatePixelsPerUnit;
                else if ( mode == Percent )
                    drawValue = ( ( cellValue + currentValueSums[ value ] ) / valueTotal ) * 100.0 * ordinatePixelsPerUnit;
                else {
                    // LineNormal or AreaNormal
                    if( bOrdinateIsLogarithmic ){
                        if( 0.0 < cellValue )
                            drawValue = log10( cellValue ) * ordinatePixelsPerUnit;
                        else
                            drawValue = -10250.0;
                        //qDebug("\nlogarithmic calc  -  cellValue: %f   drawValue: %f",
                        //        cellValue, drawValue );
                    }else{
                        drawValue = cellValue * ordinatePixelsPerUnit * (bOrdinateDecreasing ? -1.0 : 1.0);
                        //qDebug("\nlinear calc  -  cellValue: %f\n             -  drawValue: %f",
                        //        cellValue, drawValue );
                    }
                }


                // calculate Abscissa axis value
                // -----------------------------
                double xValue;
                bool skipMe = !calculateAbscissaAxisValue( vValX, ai, value,
                                                           xValue );


                // calculate and store the point and region / draw the marker
                // ----------------------------------------------------------
                if( !skipMe ){
                    // prevent the point from being toooo far
                    // below the bottom (or above the top, resp.)
                    // of the cliprect
                    double pY = QMIN( zeroXAxisI - drawValue,
                                      (logHeight + axisYOffset) * 3 );
                    pY = QMAX( pY, -(logHeight + axisYOffset) * 3 );
                    // specify the Point
                    int myPointX = static_cast < int > ( xValue ) + xShift;
                    int myPointY = static_cast < int > ( pY );

                    if( cellPropID == curPropSetId &&
                        myPointX == prevPointX &&
                        myPointY == prevPointY ){
                        allPoints[   static_cast < int > ( datasetEnd-dataset )
                                     * arrayNumValues + value ].setSkipThis( true );
                        skipMe = true;
                        //qDebug("skipped");
                    }else{
                        // use typecast to make it compile on windows using qt232
                        allPoints[   static_cast < int > ( datasetEnd-dataset )
                                     * arrayNumValues + value ].set( myPointX, myPointY, cellValue );
                        //qDebug("ok");
                    }
                    if( !skipMe ){
                        // --------------------------------------------------------
                        // determine any 'extra' properties assigned to this cell
                        // by traversing the property set chain (if necessary)
                        // --------------------------------------------------------
                        if( cellPropID != curPropSetId ){
                            //qDebug("b. ( curPropSetId: %i )",curPropSetId);
                            //qDebug("b. cellPropID: %i",cellPropID);
                            //qDebug(curPropSet.name().latin1());
                            if( cellPropID != KDChartPropertySet::UndefinedID &&
                                params()->calculateProperties( cellPropID,
                                                               curPropSet ) ){
                                curPropSetId = cellPropID;
                                //qDebug("c. curPropSetId: %i",curPropSetId);
                                //qDebug(curPropSet.name().latin1());
                            }else{
                                curPropSetId = KDChartPropertySet::UndefinedID;
                            }
                        }
                        // make sure any extra horiz. and/or vert. lines and/or markers
                        // are drawn *before* the data lines and/or markers are painted
                        if( mChartType == KDChartParams::Line ){
                            if( curPropSetId != KDChartPropertySet::UndefinedID ){
                                drawExtraLinesAndMarkers(
                                                         curPropSet,
                                                         default2DPen,
                                                         defaultMarkerStyle,
                                                         myPointX, myPointY,
                                                         painter,
                                                         ai.abscissaPara,
                                                         ordinatePara,
                                                         logWidth/1000.0,
                                                         logHeight/1000.0,
                                                         false );
                            }
                        }
                        prevPointX = myPointX;
                        prevPointY = myPointY;
                    }
                }
                // calculate running sum for stacked and percent
                if ( mode == Stacked || mode == Percent ) {
                    if( cellValue == KDCHART_POS_INFINITE )
                        currentValueSums[ value ] = KDCHART_POS_INFINITE;
                    else if( currentValueSums[ value ] != KDCHART_POS_INFINITE )
                        currentValueSums[ value ] += cellValue;
                }
            }
        }
    }



    QPointArray previousPoints; // no vector since only areas need it,
    // and these do not support 3d yet

    // Store some (dataset-independend) default values
    // to be used unless other properties
    // have been specified for the respective data cell:
    //
    const bool defaultDrawMarkers = mDrawMarkers;

    for ( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {

        // Store some (dataset-dependend) default values
        // to be used unless other properties
        // have been specified for the respective data cell:
        //
        const QPen default2DPen(   params()->lineColor().isValid()
                                   ? params()->lineColor()
                                   : params()->dataColor( dataset ),
                                   params()->lineWidth(),
                                   params()->lineStyle( dataset ) );
        bool currentDrawMarkers = defaultDrawMarkers;
        const KDChartParams::LineMarkerStyle markerStyle = params()->lineMarkerStyle( dataset );

        // the +2 is for the areas (if any)
        QPtrVector< QPointArray > points( 2 );
        points.setAutoDelete( true );
        /* Pending Michel - we need to keep track of the 
         * non rotated points for 3D lines
         */
        QPtrVector< QPointArray > oripoints( 2 );
        oripoints.setAutoDelete( true );
        
        int i = 0;
        for( i = 0; i < 2; ++i ) {
            points.insert( i, new QPointArray( ai.numValues + 2 ) );
            oripoints.insert( i, new QPointArray( ai.numValues + 2 ) );
        }

        if( ai.bAbscissaHasTrueAxisDtValues )
            ai.numValues = data->cols();

        int point = 0;

        for ( int value = 0; value < ai.numValues; ++value ) {

            // determine and store marker properties assigned to this cell
            // -----------------------------------------------------------
            currentDrawMarkers = defaultDrawMarkers;
            int cellPropID;
            if( data->cellProp( dataset, value, cellPropID ) &&
                cellPropID != curPropSetId ){
                if( cellPropID != KDChartPropertySet::UndefinedID &&
                    params()->calculateProperties( cellPropID,
                                                   curPropSet ) )
                    curPropSetId = cellPropID;
                else
                    curPropSetId = KDChartPropertySet::UndefinedID;
            }
            if( curPropSetId != KDChartPropertySet::UndefinedID ){
                // we can safely call the following functions and ignore their
                // return values since they will touch the parameters' values
                // if the propSet *contains* corresponding own values only.
                int iDummy;
                curPropSet.hasOwnShowMarker( iDummy, currentDrawMarkers );
            }


            int iVec = static_cast < int > ( datasetEnd-dataset ) * arrayNumValues + value;
            if( allPoints[ iVec ].bValid && !allPoints[ iVec ].bSkipThis ){
                const MyPoint& mp = allPoints[iVec];

                
                //qDebug("\np.x() %i        p.y() %i", p.x(), p.y() );
                // For 3D lines, we need two points (that lie
                // behind each other on the Z axis). For 2D lines and
                // areas, we need only one point.
                if( showThreeDLines ) {
                    points[0]->setPoint( point, project( mp.p.x(), mp.p.y(),
                                                         (datasetStart+dataset)*params()->threeDLineDepth() ) );
                    points[1]->setPoint( point, project( mp.p.x(), mp.p.y(),
                                                         (datasetStart+dataset + 1)*params()->threeDLineDepth() ) );
                    oripoints[0]->setPoint( point,  mp.p.x(), mp.p.y() );
                    oripoints[1]->setPoint( point,  mp.p.x() -  (datasetStart+dataset + 1)*params()->threeDLineDepth(), 
                                            mp.p.y() -  (datasetStart+dataset + 1)*params()->threeDLineDepth() );
		 
                } else
                    // 2D lines or areas
                    points[0]->setPoint( point, mp.p );
                ++point;

                int x = mp.p.x();
                int y = QMAX(QMIN(mp.p.y(),
                                  static_cast < int > (logHeight +axisYOffset)),
                             0);
                bool markerIsOutside = y != mp.p.y();
                // draw the marker and store the region
                if ( currentDrawMarkers ){
                    uint   theAlignment = Qt::AlignCenter;
                    bool   hasOwnSize = false;
                    int    theWidth  = 0;
                    int    theHeight = 0;
                    QColor theColor(params()->dataColor( dataset ));
                    int    theStyle = markerStyle;
                    if( curPropSetId != KDChartPropertySet::UndefinedID ){
                        // we can safely call the following functions and ignore their
                        // return values since they will touch the parameters' values
                        // if the propSet *contains* corresponding own values only.
                        int iDummy;
                        curPropSet.hasOwnMarkerAlign( iDummy, theAlignment );
                        curPropSet.hasOwnMarkerColor( iDummy, theColor );
                        curPropSet.hasOwnMarkerStyle( iDummy, theStyle );
                        QSize size(theWidth, theHeight);
                        hasOwnSize = curPropSet.hasOwnMarkerSize(iDummy, size);
                        if( hasOwnSize ){
                            theWidth  = size.width();
                            theHeight = size.height();
                        }
                    }

                    drawMarker( painter,
                                params(),
                                _areaWidthP1000, _areaHeightP1000,
                                _dataRect.x(),
                                _dataRect.y(),
                                markerIsOutside
                                ? KDChartParams::LineMarker1Pixel
                                : theStyle,
                                theColor,
                                QPoint(x,y),
                                dataset, value, chart, regions,
                                hasOwnSize ? &theWidth  : 0,
                                hasOwnSize ? &theHeight : 0,
                                theAlignment );

                }
                // store the region
                else if( regions ) {
                    QRect rect(
                        QPoint( x-params()->lineWidth()-1, y-params()->lineWidth()-1 ),
                        QPoint( x+params()->lineWidth()+1, y+params()->lineWidth()+1 )
                        );
                    rect.moveBy( _dataRect.x(), _dataRect.y() );
                    regions->append(
                                    new KDChartDataRegion(dataset, value, chart, rect) );
                }

            }
        }
        if ( point ) {
            bool bDrawLines = (0 != params()->lineWidth());
          
            if ( mIsArea ) {
                // first draw with the fill brush, no pen, with the
                // zero axis points or upper border points added for the first
                // dataset or with the previous points reversed for all other
                // datasets.
                painter->setPen( QPen( Qt::NoPen ) );
                const QBrush datasetBrush( params()->dataColor( dataset ), Qt::SolidPattern );
                painter->setBrush( datasetBrush );
                QBrush currentBrush( datasetBrush );

                if ( mode == Normal || dataset == (int)datasetEnd ) {
                    /// first dataset (or any dataset in normal mode, where
                    /// the datasets overwrite each other)

                    // no 3d handling for areas yet
                    QPoint lastPoint = points[0]->point( point - 1 );

                    // zeroXAxisI can be too far below the abscissa, but it's
                    // the only thing we have. Likewise can 0 be too far above
                    // the upper boundary, but again it's the only thing we
                    // have, at the rest is clipped anyway.
                    int yCoord;
                    if ( params()->areaLocation() == KDChartParams::AreaBelow ||
                         mode == Percent )
                        yCoord = static_cast<int>(zeroXAxisI);
                    else
                        yCoord = static_cast<int>(axisYOffset);

                    // old: draw the complete area in on go:
                    /*
                    // no 3d handling for areas yet
                    points[0]->setPoint( point, lastPoint.x(), yCoord );
                    point++;

                    QPoint firstPoint = points[0]->point( 0 );
                    points[0]->setPoint( point, firstPoint.x(), yCoord );
                    point++;

                    painter->drawPolygon( *points[0], false, 0, point );
                    */

                    // new: draw individual area segments:
                    curPropSetId = KDChartPropertySet::UndefinedID;
                    for( int value = 0; value < point-1; ++value ) {

                        int cellPropID;
                        if( data->cellProp( dataset, value, cellPropID ) &&
                            cellPropID != curPropSetId ){

                            if( cellPropID != KDChartPropertySet::UndefinedID &&
                                params()->calculateProperties( cellPropID,
                                                               curPropSet ) ){
                                curPropSetId = cellPropID;
                            }else{
                                curPropSetId = KDChartPropertySet::UndefinedID;
                            }
                            // preset with default value
                            QBrush theAreaBrush = datasetBrush;

                            if( curPropSetId != KDChartPropertySet::UndefinedID ){
                                // we can safely call the following functions and ignore their
                                // return values since they will touch the parameters' values
                                // if the propSet *contains* corresponding own values only.
                                int iDummy;
                                curPropSet.hasOwnAreaBrush( iDummy, theAreaBrush );
                            }
                            painter->setBrush( theAreaBrush );

                        }
                        QPointArray segment( 4 );
                        segment.setPoint( 0, points[0]->point( value                 ) );
                        segment.setPoint( 1, points[0]->point( value+1               ) );
                        segment.setPoint( 2, points[0]->point( value+1 ).x(), yCoord );
                        segment.setPoint( 3, points[0]->point( value   ).x(), yCoord );                        
                        painter->drawPolygon( segment );
                    }

                    // old: draw the complete area in on go:
                    /*
                    // remove the last two points added
                    point -= 2;
                    */
                    //qDebug("\n111");
                } //  if ( mode == Normal || dataset == (int)datasetEnd )
                else {
                    // don't mess around with the original array; we'll need
                    // that for the next time through.

                    //qDebug("222");
                    // no 3d handling for areas yet
                    QPointArray thisSection = points[0]->copy();

                    thisSection.resize( point + previousPoints.size() );
                    // append the previous array (there is guaranteed to be
                    // one because we are at least the second time through
                    // here) in reverse order
                    for ( unsigned int i = 0; i < previousPoints.size(); ++i ) {
                        thisSection.setPoint( point + i,
                                              previousPoints.point( previousPoints.size() - i - 1 ) );
                        //qDebug("\nx: %i",previousPoints.point( previousPoints.size() - i - 1 ).x());
                        //qDebug("y: %i",previousPoints.point( previousPoints.size() - i - 1 ).y());
                    }
                    painter->drawPolygon( thisSection );
                }
                // draw the line with no brush and outline color
                painter->setBrush( Qt::NoBrush );
                painter->setPen( QPen( params()->outlineDataColor(),
                                       params()->outlineDataLineWidth() ) );
            } else {
                // line
                if( showThreeDLines ) {
                    // This is a 3D line:
                    // We draw the line with the data color brush
                    //                   and the outline data pen.
                    painter->setBrush( params()->dataColor( dataset ) );
                    painter->setPen( QPen( params()->outlineDataColor(),
                                           params()->outlineDataLineWidth() ) );
                } else {
                    // This is a 2D line:
                    // We draw the line with the no brush
                    // and the data color if no special line color was specified.
                    painter->setBrush( Qt::NoBrush );
                    painter->setPen( default2DPen );
                }
            }

            // Neither draw the contour line if this is a pure Point chart
            // nor draw it for the last row of a percent area chart.
           
            if( bDrawLines &&
                ( (mode != Percent) || !mIsArea || (dataset != (int)datasetEnd) ) ){
                if( showThreeDLines ) {
		 
                    // A 3D line needs to be drawn piece-wise
                    for ( int value = 0; value < point-1; ++value ) {
                        //          if( data->cell( dataset, value ).hasValue() &&
                        //              data->cell( dataset, value+1 ).hasValue() ) {
                        //      qDebug( "Draw a segment in dataset %d from %d to %d", dataset, value, value+1 );
                
                        //store the rotated points ( see project() )
                        QPointArray rotatedSegment( 4 );                        
                        rotatedSegment.setPoint( 0, points[0]->point( value ));
                        rotatedSegment.setPoint( 1, points[0]->point( value+1 ) );
                        rotatedSegment.setPoint( 2, points[1]->point( value+1 ) );
                        rotatedSegment.setPoint( 3, points[1]->point( value ) );

                        //store the true points without rotation    
                        QPointArray trueSegment( 4 );			 
                        trueSegment.setPoint( 0, oripoints[0]->point( value ));
                        trueSegment.setPoint( 1, oripoints[0]->point( value+1 ) );
                        trueSegment.setPoint( 2, oripoints[1]->point( value+1 ) );
                        trueSegment.setPoint( 3, oripoints[1]->point( value ) );

                        // calculate the rotated points position relative to each other
                        // we will then be able to keep the rotation ( see: project () )
                        // by reporting this position relative to the true segment line 
                        //left side pt3 and pt0 
                        int dx30 = rotatedSegment.point(3).x() - rotatedSegment.point(0).x();
                        int dy30 = rotatedSegment.point(3).y() - rotatedSegment.point(0).y(); 
                        //right side pt1 and pt2
                        int dx12 = rotatedSegment.point(2).x() - rotatedSegment.point(1).x();
                        int dy12 = rotatedSegment.point(2).y() - rotatedSegment.point(1).y();

                        // store and paint the "3D" segment
                        QPointArray segment( 4 );
                        segment.setPoint( 0, trueSegment.point(0) );
                        segment.setPoint( 1, trueSegment.point(1) );
                        segment.setPoint( 2, trueSegment.point(1).x() + dx12, trueSegment.point(1).y() + dy12 );
                        segment.setPoint( 3, trueSegment.point(0).x() + dx30, trueSegment.point(0).y() + dy30);

		       
                        //PENDING Michel 3dlines drawing a segment with showThreeDLines                       
                        painter->drawPolygon( segment );
		       
                      			
                        //          } else
                        //              qDebug( "Can't draw a segment in dataset %d from %d to %d", dataset, value, value+1 );
                    }
                } else {
                    QPoint p1, p2;
                    // Note: If markers are drawn very near to each other
                    //       and tiny markers are used
                    //       we don't draw the connecting lines.
                    bool b4PMarkers = KDChartParams::LineMarker4Pixels == markerStyle;
                    bool bTinyMarkers =
                        KDChartParams::LineMarker1Pixel  == markerStyle || b4PMarkers;
                    curPropSetId = KDChartPropertySet::UndefinedID;
                    painter->setPen( default2DPen );
                    for ( int value = 0; value < point-1; ++value ) {
                        p1 = points[0]->point( value   );
                        p2 = points[0]->point( value+1 );

                        // Determine properties assigned to this cell
                        // and change the painter if necessarry:
                        currentDrawMarkers = defaultDrawMarkers;
                        int cellPropID;
                        if( data->cellProp( dataset, value, cellPropID ) &&
                            cellPropID != curPropSetId ){
                            if( cellPropID != KDChartPropertySet::UndefinedID &&
                                params()->calculateProperties( cellPropID,
                                                               curPropSet ) ){
                                curPropSetId = cellPropID;
                            }else{
                                curPropSetId = KDChartPropertySet::UndefinedID;
                            }
                            // preset with default values
                            int          theLineWidth = default2DPen.width();
                            QColor       theLineColor = default2DPen.color();
                            Qt::PenStyle theLineStyle = default2DPen.style();
                            if( curPropSetId != KDChartPropertySet::UndefinedID ){
                                // we can safely call the following functions and ignore their
                                // return values since they will touch the parameters' values
                                // if the propSet *contains* corresponding own values only.
                                int iDummy;
                                curPropSet.hasOwnLineWidth ( iDummy, theLineWidth );
                                curPropSet.hasOwnLineColor ( iDummy, theLineColor );
                                curPropSet.hasOwnLineStyle ( iDummy, theLineStyle );
                                curPropSet.hasOwnShowMarker( iDummy, currentDrawMarkers );
                            }
                            painter->setPen( QPen( theLineColor,
                                                   theLineWidth,
                                                   theLineStyle ) );
                        }

                        if( !currentDrawMarkers ){
                            //PENDING Michel: drawing a line - not currentMarkers
                            painter->drawLine( p1, p2 );
                        }else{
                            int dx = p2.x() - p1.x();
                            int dy = p2.y() - p1.y();
                            if( !bTinyMarkers || (abs(dx) > 4) || (abs(dy) > 4) ){
                                if( bTinyMarkers ) {
                                    double m  = !dx ? 100.0
                                        : !dy ? 0.01
                                        : ((double)dy / (double)dx);
                                    double am = fabs(m);
                                    int dxx;
                                    int dyy;
                                    if( 0.25 > am ){
                                        dxx = 3;
                                        dyy = 0;
                                    }else if( 0.67 > am ){
                                        dxx = 3;
                                        dyy = 1;
                                    }else if( 1.33 > am ){
                                        dxx = 2;
                                        dyy = 2;
                                    }else if( 4.0 > am ){
                                        dxx = 1;
                                        dyy = 3;
                                    }else{
                                        dxx = 0;
                                        dyy = 3;
                                    }
                                    if( 0 > dx )
                                        dxx *= -1;
                                    if( 0 > dy )
                                        dyy *= -1;
                                    if( b4PMarkers ){
                                        if( 0 < dx )
                                            ++p1.rx();
                                        else if( 0 > dx )
                                            ++p2.rx();
                                        if( 0 < dy )
                                            ++p1.ry();
                                        else if( 0 > dy )
                                            ++p2.ry();
                                    }
                                    p1.rx() += dxx; p1.ry() += dyy;
                                    p2.rx() -= dxx; p2.ry() -= dyy;
                                }
                                //PENDING Michel: drawing a line - currentMarkers
                                painter->drawLine( p1, p2 );
                            }
                        }
                    }
                }
            }
        }

        // Save point array for next way through (needed for e.g. stacked
        // areas), not for 3D currently
        points[0]->resize( point );
        previousPoints = points[0]->copy();
    }


    // Now draw any extra lines (and/or their markers, resp.) that
    // are to be printed IN FRONT of the normal lines:
    if( mChartType == KDChartParams::Line ){
        for( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {

            const KDChartParams::LineMarkerStyle
                defaultMarkerStyle = params()->lineMarkerStyle( dataset );
            const QPen default2DPen(   params()->lineColor().isValid()
                                       ? params()->lineColor()
                                       : params()->dataColor( dataset ),
                                       params()->lineWidth(),
                                       params()->lineStyle( dataset ) );

            if( ai.bAbscissaHasTrueAxisDtValues )
                ai.numValues = data->cols();

            for ( int value = 0; value < ai.numValues; ++value ) {
                int iVec = static_cast < int > ( datasetEnd-dataset ) * arrayNumValues + value;
                if( allPoints[ iVec ].bValid ){
                    const MyPoint& mp = allPoints[iVec];
                    //qDebug("\np.x() %i        p.y() %i", p.x(), p.y() );

                    // --------------------------------------------------------
                    // determine any 'extra' properties assigned to this cell
                    // by traversing the property set chain (if necessary)
                    // --------------------------------------------------------
                    int cellPropID;
                    if( data->cellProp( dataset, value, cellPropID ) &&
                        cellPropID != curPropSetId ){
                        if( cellPropID != KDChartPropertySet::UndefinedID &&
                            params()->calculateProperties( cellPropID,
                                                           curPropSet ) )
                            curPropSetId = cellPropID;
                        else
                            curPropSetId = KDChartPropertySet::UndefinedID;
                    }
                    if( curPropSetId != KDChartPropertySet::UndefinedID ){
                        drawExtraLinesAndMarkers(
                                                 curPropSet,
                                                 default2DPen,
                                                 defaultMarkerStyle,
                                                 mp.p.x(), mp.p.y(),
                                                 painter,
                                                 ai.abscissaPara,
                                                 ordinatePara,
                                                 logWidth/1000.0,
                                                 logHeight/1000.0,
                                                 true );
                    }
                }
            }
        }
    }
    //qDebug(const_cast < KDChartParams* > ( params() )->properties( KDCHART_PROPSET_NORMAL_DATA )->name().latin1());
    //qDebug(const_cast < KDChartParams* > ( params() )->properties( KDCHART_PROPSET_TRANSPARENT_DATA )->name().latin1());
    //qDebug(const_cast < KDChartParams* > ( params() )->properties( KDCHART_PROPSET_HORI_LINE )->name().latin1());
    //qDebug(const_cast < KDChartParams* > ( params() )->properties( KDCHART_PROPSET_VERT_LINE )->name().latin1());
    //qDebug("--");
    }
Exemplo n.º 14
0
static void addPoint( QPointArray &a, const QPoint &p )
{
    uint n = a.size();
    a.resize( n + 1 );
    a.setPoint( n, p );
}
Exemplo n.º 15
0
void toBarChart::paintChart ( QPainter *p, QRect &rect )
{
    QFontMetrics fm = p->fontMetrics();

    if ( !Zooming ) {
        if ( MinAuto ) {
            bool first = true;
            std::list<std::list<double> >::reverse_iterator i = Values.rbegin();
            if ( i != Values.rend() ) {
                for ( std::list<double>::iterator j = ( *i ).begin();j != ( *i ).end();j++ ) {
                    if ( first ) {
                        first = false;
                        zMinValue = *j;
                    } else if ( zMinValue > *j )
                        zMinValue = *j;
                }
            }
        }
        if ( MaxAuto ) {
            bool first = true;
            std::list<double> total;
            {
                for ( std::list<std::list<double> >::iterator i = Values.begin();i != Values.end();i++ ) {
                    std::list<double>::iterator k = total.begin();
                    for ( std::list<double>::iterator j = ( *i ).begin();j != ( *i ).end();j++ ) {
                        if ( k == total.end() ) {
                            total.insert ( total.end(), *j );
                            k = total.end();
                        } else {
                            *k += *j;
                            k++;
                        }
                    }
                }
            }
            for ( std::list<double>::iterator i = total.begin();i != total.end();i++ ) {
                if ( first ) {
                    first = false;
                    zMaxValue = *i;
                } else if ( zMaxValue < *i )
                    zMaxValue = *i;
            }
        }
        if ( !MinAuto )
            zMinValue = MinValue;
        else
            zMinValue = round ( zMinValue, false );
        if ( !MaxAuto )
            zMaxValue = MaxValue;
        else
            zMaxValue = round ( zMaxValue, true );
    }

    paintTitle ( p, rect );
    paintLegend ( p, rect );
    paintAxis ( p, rect );

    std::list<QPointArray> Points;
    int cp = 0;
    int samples = countSamples();
    int zeroy = int ( rect.height() - 2 - ( -zMinValue / ( zMaxValue - zMinValue ) * ( rect.height() - 4 ) ) );
    if ( samples > 1 ) {
        const QWMatrix & mtx = p->worldMatrix();
        p->setClipRect ( int ( mtx.dx() + 2 ), int ( mtx.dy() + 2 ), rect.width() - 3, rect.height() - 3 );
        if ( Zooming )
            p->drawText ( 2, 2, rect.width() - 4, rect.height() - 4,
                          AlignLeft | AlignTop, "Zoom" );
        for ( std::list<std::list<double> >::reverse_iterator i = Values.rbegin();i != Values.rend();i++ ) {
            std::list<double> &val = *i;
            int count = 0;
            int skip = SkipSamples;
            QPointArray a ( samples + 10 );
            int x = rect.width() - 2;
            for ( std::list<double>::reverse_iterator j = val.rbegin();j != val.rend() && x >= 2;j++ ) {
                if ( skip > 0 )
                    skip--;
                else {
                    int val = int ( rect.height() - 2 - ( ( *j - zMinValue ) / ( zMaxValue - zMinValue ) * ( rect.height() - 4 ) ) );
                    x = rect.width() - 2 - count * ( rect.width() - 4 ) / ( samples - 1 );
                    a.setPoint ( count, x, val );
                    count++;
                    if ( count >= samples )
                        break;
                }
            }
            a.resize ( count * 2 );
            Points.insert ( Points.end(), a );
            cp++;
        }
    }

    std::map<int, int> Bottom;
    for ( std::list<QPointArray>::iterator i = Points.begin();i != Points.end();i++ ) {
        QPointArray a = *i;
        int lx = 0;
        int lb = 0;
        for ( unsigned int j = 0;j < a.size() / 2;j++ ) {
            int x, y;
            a.point ( j, &x, &y );
            if ( Bottom.find ( x ) == Bottom.end() )
                Bottom[x] = 0;
            if ( lx != x )
                lb = Bottom[x];
            a.setPoint ( a.size() - 1 - j, x, zeroy - lb );
            y -= lb;
            a.setPoint ( j, x, y );
            Bottom[x] = zeroy - y;
            lx = x;
        }

        p->save();
        /*
            p->setBrush(toChartColor(--cp));
        */
        p->drawPolygon ( a );
        p->restore();
    }
}
Exemplo n.º 16
0
/**
  Internal method that draws one of the pies in a pie chart.

  \param painter the QPainter to draw in
  \param dataset the dataset to draw the pie for
  \param pie the pie to draw
  \param the chart to draw the pie in
  \param regions a pointer to a list of regions that will be filled
  with regions representing the data segments, if not null
  */
void KDChartPiePainter::drawOnePie( QPainter* painter,
        KDChartTableDataBase* /*data*/,
        uint dataset, uint pie, uint chart,
        uint threeDPieHeight,
        KDChartDataRegionList* regions )
{
    // Is there anything to draw at all?
    int angleLen = _angleLens[ ( int ) pie ];
    if ( angleLen ) {
        int startAngle = _startAngles[ ( int ) pie ];

        KDChartDataRegion* datReg = 0;
        QRegion* region = 0;
        bool mustDeleteRegion = false;
        if ( regions ){
            region = new QRegion();
            mustDeleteRegion = true;
        }

        QRect drawPosition = _position;
        if ( params()->explode() ) {
            // need to compute a new position for each or some of the pie
            QValueList<int> explodeList = params()->explodeValues();
            if( explodeList.count() == 0 || // nothing on list, explode all
                    explodeList.find( pie ) != explodeList.end() ) {
                double explodeAngle = ( startAngle + angleLen / 2 ) / 16;
                double explodeAngleRad = DEGTORAD( explodeAngle );
                double cosAngle = cos( explodeAngleRad );
                double sinAngle = -sin( explodeAngleRad );

                // find the explode factor for this particular pie
                double explodeFactor = 0.0;
                QMap<int,double> explodeFactors = params()->explodeFactors();
                if( !explodeFactors.contains( pie ) ) // not on factors list, use default
                    explodeFactor = params()->explodeFactor();
                else // on factors list, use segment-specific value
                    explodeFactor = explodeFactors[pie];

                double explodeX = explodeFactor * _size * cosAngle;
                double explodeY = explodeFactor * _size * sinAngle;
                drawPosition.moveBy( static_cast<int>( explodeX ), static_cast<int>( explodeY ) );
            } else
                drawPosition = _position;
        } else
            drawPosition = _position;

        // The 3D effect needs to be drawn first because it could
        // otherwise partly hide the pie itself.
        if ( params()->threeDPies() ) {
            draw3DEffect( painter, drawPosition, dataset, pie, chart,
                          threeDPieHeight,
                          params()->explode(), region );
        }

        painter->setBrush( params()->dataColor( pie ) );
        if ( angleLen == 5760 ) {
            // full circle, avoid nasty line in the middle
            painter->drawEllipse( drawPosition );
            if ( regions ) {
                QPointArray hitregion;
                hitregion.makeEllipse( drawPosition.x(), drawPosition.y(),
                                       drawPosition.width(),
                                       drawPosition.height() );
                datReg = new KDChartDataRegion( region->unite( QRegion( hitregion ) ),
                                                dataset,
                                                pie,
                                                chart );
                datReg->points[ KDChartEnums::PosCenter ]
                    = drawPosition.center();
                datReg->points[ KDChartEnums::PosCenterRight ]
                    = pointOnCircle( drawPosition,    0 );
                datReg->points[ KDChartEnums::PosTopRight ]
                    = pointOnCircle( drawPosition,  720 );
                datReg->points[ KDChartEnums::PosTopCenter ]
                    = pointOnCircle( drawPosition, 1440 );
                datReg->points[ KDChartEnums::PosTopLeft ]
                    = pointOnCircle( drawPosition, 2160 );
                datReg->points[ KDChartEnums::PosCenterLeft ]
                    = pointOnCircle( drawPosition, 2880 );
                datReg->points[ KDChartEnums::PosBottomLeft ]
                    = pointOnCircle( drawPosition, 3600 );
                datReg->points[ KDChartEnums::PosBottomCenter ]
                    = pointOnCircle( drawPosition, 4320 );
                datReg->points[ KDChartEnums::PosBottomRight ]
                    = pointOnCircle( drawPosition, 5040 );
                datReg->startAngle = 2880;
                datReg->angleLen   = 5760;
                regions->append( datReg );
            }
        } else {
            // draw the top of this piece
            // Start with getting the points for the arc.
            const int arcPoints = angleLen;
            QPointArray collect(arcPoints+2);
            int i=0;
            for ( ; i<=angleLen; ++i){
                collect.setPoint(i, pointOnCircle( drawPosition, startAngle+i ));
            }
            // Adding the center point of the piece.
            collect.setPoint(i, drawPosition.center() );



            painter->drawPolygon( collect );

//if( bHelp ){
//              painter->drawPolyline( collect );
//bHelp=false;
//}



            if ( regions ) {
                QPointArray hitregion;
                hitregion.makeArc( drawPosition.x(), drawPosition.y(),
                        drawPosition.width(),
                        drawPosition.height(),
                        ( int ) startAngle, ( int ) angleLen );
                hitregion.resize( hitregion.size() + 1 );
                hitregion.setPoint( hitregion.size() - 1,
                        drawPosition.center() );
                datReg = new KDChartDataRegion( region->unite( QRegion( hitregion ) ),
                                                dataset,
                                                pie,
                                                chart );

                datReg->points[ KDChartEnums::PosTopLeft ]
                    = pointOnCircle( drawPosition, startAngle + angleLen );
                datReg->points[ KDChartEnums::PosTopCenter ]
                    = pointOnCircle( drawPosition, startAngle + angleLen / 2 );
                datReg->points[ KDChartEnums::PosTopRight ]
                    = pointOnCircle( drawPosition, startAngle );

                datReg->points[   KDChartEnums::PosBottomLeft   ] = drawPosition.center();
                datReg->points[   KDChartEnums::PosBottomCenter ]
                    = datReg->points[ KDChartEnums::PosBottomLeft   ];
                datReg->points[   KDChartEnums::PosBottomRight  ]
                    = datReg->points[ KDChartEnums::PosBottomLeft   ];

                datReg->points[ KDChartEnums::PosCenterLeft ]
                    = QPoint( (   datReg->points[ KDChartEnums::PosTopLeft      ].x()
                                + datReg->points[ KDChartEnums::PosBottomLeft   ].x() ) / 2,
                            (   datReg->points[ KDChartEnums::PosTopLeft      ].y()
                                + datReg->points[ KDChartEnums::PosBottomLeft   ].y() ) / 2 );
                datReg->points[ KDChartEnums::PosCenter ]
                    = QPoint( (   datReg->points[ KDChartEnums::PosTopCenter    ].x()
                                + datReg->points[ KDChartEnums::PosBottomCenter ].x() ) / 2,
                            (   datReg->points[ KDChartEnums::PosTopCenter    ].y()
                                + datReg->points[ KDChartEnums::PosBottomCenter ].y() ) / 2 );
                datReg->points[ KDChartEnums::PosCenterRight ]
                    = QPoint( (   datReg->points[ KDChartEnums::PosTopRight     ].x()
                                + datReg->points[ KDChartEnums::PosBottomRight  ].x() ) / 2,
                            (   datReg->points[ KDChartEnums::PosTopRight     ].y()
                                + datReg->points[ KDChartEnums::PosBottomRight  ].y() ) / 2 );

                datReg->startAngle = startAngle;
                datReg->angleLen   = angleLen;
                regions->append( datReg );
            }
        }
        if( mustDeleteRegion )
            delete region;
    }
}