Ejemplo n.º 1
0
void
BarObj::finishedAdd()
{
    const ColorSpec	*colSpec = NULL;
    SoNode		*object = ViewObj::object(_shape);
    SoSeparator		*labelSep = NULL;
    SoSeparator		*metricSep = NULL;
    SoSeparator		*instSep = NULL;
    SoSeparator		*barSep = new SoSeparator;
    SoSeparator		*baseSep = new SoSeparator;
    SoTranslation	*objTran = new SoTranslation;
    SoTranslation	*barTran = new SoTranslation;
    SoTranslation	*baseTran = new SoTranslation;
    SoTranslation	*modTran = new SoTranslation;
    ColorScale		*colScale = NULL;
    LabelSide		metSide = left;
    LabelSide		instSide = left;
    Text		**metText = NULL;
    Text		**instText = NULL;
    int			i;
    int			max = 0;
    int			numMetLabels = 0;
    int			numInstLabels = 0;

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL0)
	cerr << "BarObj::finishedAdd:" << endl;
#endif

    if (_metrics.numMetrics() == 0) {
	BaseObj::addBase(_root);
	pmprintf("%s: Error: Bar object has no metrics\n",
		 pmProgname);
	_length = 0;
	_width = baseWidth();
	_depth = baseDepth();
	return;
    }

    _root->addChild(objTran);

    if (_metLabels->size() || _instLabels->size()) {
	labelSep = new SoSeparator;
	_root->addChild(labelSep);
	SoBaseColor *base = new SoBaseColor;
	base->rgb.setValue(_labelColor[0], _labelColor[1], _labelColor[2]);
	labelSep->addChild(base);
    }
    _root->addChild(barSep);
    barSep->addChild(barTran);
    barSep->addChild(baseSep);
    baseSep->addChild(baseTran);
    barSep->addChild(modTran);
    BaseObj::addBase(baseSep);

    // Determine color mapping

    if (_colors.size())
	colSpec = theColorLists.list((const char *)_colors.toLatin1());

    if (colSpec != NULL) {
        if (colSpec->_scale) {
	    if (_mod == BarMod::yScale) {
		pmprintf("%s: Warning: Color scale ignored for Y-Scale Bar object.\n",
			 pmProgname);
	    }
	    else {
		if (colSpec->_list.size() == 0)
		    colScale = new ColorScale(0.0, 0.0, 1.0);
		else {
		    colScale = new ColorScale(*(colSpec->_list[0]));
		    for (i = 1; i < colSpec->_list.size(); i++)
			colScale->add(new ColorStep(*(colSpec->_list[i]),
							colSpec->_max[i]));
		}
	    }
	}
        else if (_mod == BarMod::color || _mod == BarMod::colYScale) {
	    pmprintf("%s: Warning: Expected color scale for color modulated Bar object.\n",
		     pmProgname);

	    if (colSpec->_list.size() == 0)
		colScale = new ColorScale(0.0, 0.0, 1.0);
	    else
		colScale = new ColorScale(*(colSpec->_list[0]));
	}
    }
    else {
        pmprintf("%s: Warning: No colours specified for Bar objects, defaulting to blue.\n",
                 pmProgname);

	if (_mod == BarMod::color || _mod == BarMod::colYScale)
	    colScale = new ColorScale(0.0, 0.0, 1.0);
    }

    if (_mod == BarMod::yScale) {
	if (colSpec != NULL)
	    for (i = 0; i < colSpec->_list.size(); i++)
		_metrics.add(*(colSpec->_list)[i]);
	_metrics.resolveColors(MetricList::perMetric);
    }

    // Generate Bar Modulate Object
    if (_mod == BarMod::yScale)
	_bars = new BarMod(&_metrics, object, _dir, _group,
			   (float)_length, (float)_maxHeight, (float)_length,
			   (float)_xSpace, (float)_zSpace);
    else {
	_bars = new BarMod(&_metrics, *colScale, object, _dir, _mod, _group,
			   (float)_length, (float)_maxHeight, (float)_length,
			   (float)_xSpace, (float)_zSpace);	
    }

    barSep->addChild(_bars->root());
    BaseObj::add(_bars);

    // Generate Labels

    if (_metLabels->size()) {
	if (_dir == BarMod::instPerRow)
	    if (_metDir == away)
		metSide = below;
	    else
		metSide = above;
	else
	    if (_metDir == away)
		metSide = right;
	    else
		metSide = left;

	metricSep = new SoSeparator;
	labelSep->addChild(metricSep);

	if (_metLabels->size() < _metrics.numMetrics())
	    numMetLabels = _metLabels->size();
	else
	    numMetLabels = _metrics.numMetrics();

	metText = calcLabels(*_metLabels, metSide, numMetLabels);
    }

    if (_instLabels->size()) {
	if (_dir == BarMod::instPerCol) {
	    max = _bars->cols();
	    if (_instDir == away)
		instSide = below;
	    else
		instSide = above;
	}
	else {
	    max = _bars->rows();
	    if (_instDir == away)
		instSide = right;
	    else
		instSide = left;
	}

	instSep = new SoSeparator;
	labelSep->addChild(instSep);

	if (_instLabels->size() < max)
	    numInstLabels = _instLabels->size();
	else
	    numInstLabels = max;

	instText = calcLabels(*_instLabels, instSide, numInstLabels);
    }

    // Width and depth of bars only, effects of labels added later

    _width = _bars->width();
    _depth = _bars->depth();

    // Insert the labels

    if (numMetLabels)
	metricSep->addChild(doLabels(metText, metSide, numMetLabels));

    if (numInstLabels)
	instSep->addChild(doLabels(instText, instSide, numInstLabels));

    // Work out where the bars live

    _bars->regenerate(_length, _length, _xSpace, _zSpace);
    _width = _bars->width();
    _depth = _bars->depth();

    baseTran->translation.setValue(_width / 2.0, 0.0, _depth / 2.0);
    
    _width += (u_int32_t)(baseWidth() + _margins[left] + _margins[right]+0.5);
    _depth += (u_int32_t)(baseDepth() + _margins[above] + _margins[below]+0.5);

    objTran->translation.setValue((_width / -2.0), 0.0, (_depth / -2.0));

    barTran->translation.setValue(_margins[left] + borderX(), 0.0,
				  _margins[above] + borderZ());


    modTran->translation.setValue(0.0, 
				  (BaseObj::state() ? baseHeight() : 0.0),
				  0.0);

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL0)
	cerr << "BarObj::finishedAdd: metric list = " << endl
	     << _metrics << endl;
#endif

    if (_metrics.numMetrics())
	ViewObj::theNumModObjects++;

    // Cleanup

    if (colScale)
	delete colScale;
    delete _metLabels;
    delete _instLabels;
}