/*!
   Synchronize an axis scale according to the scale of the reference axis

  \param axis Axis index ( see QwtPlot::AxisId )
  \param reference Interval of the reference axis
  \param size Size of the canvas
*/
QwtDoubleInterval QwtPlotRescaler::syncScale(int axis, 
    const QwtDoubleInterval& reference, const QSize &size) const 
{
    double dist;
    if ( orientation(referenceAxis()) == Qt::Horizontal )
        dist = reference.width() / size.width();
    else
        dist = reference.width() / size.height();

    if ( orientation(axis) == Qt::Horizontal )
        dist *= size.width();
    else
        dist *= size.height();

    dist /= aspectRatio(axis);

    QwtDoubleInterval intv;
    if ( rescalePolicy() == Fitting )
        intv = intervalHint(axis);
    else
        intv = interval(axis);

    intv = expandInterval(intv, dist, expandingDirection(axis));

    return intv;
}
double QwtPlotRescaler::pixelDist(int axis, const QSize &size) const
{
    const QwtDoubleInterval intv = intervalHint(axis);

    double dist = 0.0;
    if ( !intv.isNull() )
    {
        if ( axis == referenceAxis() )
            dist = intv.width();
        else
        {
            const double r = aspectRatio(axis);
            if ( r > 0.0 )
                dist = intv.width() * r;
        }
    }

    if ( dist > 0.0 )
    {
        if ( orientation(axis) == Qt::Horizontal )
           dist /= size.width();
        else
           dist /= size.height();
    }

    return dist;
}
예제 #3
0
/*!
   \brief Calculate a scale division

   \param x1 First interval limit 
   \param x2 Second interval limit 
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.

   \sa QwtScaleEngine::stepSize(), QwtScaleEngine::subDivide()
*/
QwtScaleDiv QwtLinearScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    if (interval.width() <= 0 )
        return QwtScaleDiv();

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 )
    {
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

        stepSize = divideInterval(interval.width(), maxMajSteps);
    }

    QwtScaleDiv scaleDiv;

    if ( stepSize != 0.0 )
    {
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
        buildTicks(interval, stepSize, maxMinSteps, ticks);

        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
/*!
   \brief Calculate a scale division

   \param x1 First interval limit
   \param x2 Second interval limit
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.
*/
QwtScaleDiv ProbabilityScaleEngine::divideScale(double x1, double x2,
    int, int, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    interval = interval.limited(1e-4, 99.999);

    if (interval.width() <= 0 )
        return QwtScaleDiv();

    stepSize = fabs(qRound(stepSize));
    if ( stepSize == 0.0 )
        stepSize = 1.0;

    QwtScaleDiv scaleDiv;
    if ( stepSize != 0.0 ){
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
		buildTicks(interval, stepSize, ticks);
        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
void ColorMapEditor::insertLevel()
{
int row = table->currentRow();
QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);

double val = 0.5*(table->item(row, 0)->text().toDouble() + table->item(row - 1, 0)->text().toDouble());
double mapped_val = (val - min_val)/range.width();
QColor c = QColor(color_map.rgb(QwtDoubleInterval(0, 1), mapped_val));

table->blockSignals(true);
table->insertRow(row);

QTableWidgetItem *it = new QTableWidgetItem(QString::number(val));
table->setItem(row, 0, it);
		
it = new QTableWidgetItem(c.name());
it->setFlags(Qt::ItemFlags(!Qt::ItemIsEditable));
it->setBackground(QBrush(c));
it->setForeground(QBrush(c));
table->setItem(row, 1, it);
table->blockSignals(false);
	
enableButtons(table->currentRow(), 0);
updateColorMap();
}
void ColorMapEditor::setColorMap(const QwtLinearColorMap& map)
{
scaleColorsBox->setChecked(map.mode() == QwtLinearColorMap::ScaledColors);

QwtArray <double> colors = map.colorStops();
int rows = (int)colors.size();
table->setRowCount(rows);
table->blockSignals(true);
	
for (int i = 0; i < rows; i++)
	{
	QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);
	double val = min_val + colors[i] * range.width();
		
	QTableWidgetItem *it = new QTableWidgetItem(QString::number(val));
    table->setItem(i, 0, it);
		
	QColor c = QColor(map.rgb(QwtDoubleInterval(0, 1), colors[i]));
	it = new QTableWidgetItem(c.name());
	it->setFlags(Qt::ItemFlags(!Qt::ItemIsEditable));
	it->setBackground(QBrush(c));
	it->setForeground(QBrush(c));
    table->setItem(i, 1, it);
	}
table->blockSignals(false);
	
color_map = map;
}
예제 #7
0
/**
 * Normalize the value to the range[0,1]
 * @param interval :: The data range
 * @param value :: The data value
 * @returns The fraction along the given interval using the current scale type
 */
double MantidColorMap::normalize(const QwtDoubleInterval &interval,
                                 double value) const {
  // nan numbers have the property that nan != nan, treat nan as being invalid
  if (interval.isNull() || m_num_colors == 0 || boost::math::isnan(value))
    return m_nan;

  const double width = interval.width();
  if (width <= 0.0 || value <= interval.minValue())
    return 0.0;

  if (value >= interval.maxValue())
    return 1.0;

  double ratio(0.0);
  if (m_scale_type == GraphOptions::Linear) {
    ratio = (value - interval.minValue()) / width;
  } else if (m_scale_type == GraphOptions::Power) {
    ratio = (pow(value, m_nth_power) - pow(interval.minValue(), m_nth_power)) /
            (pow(interval.maxValue(), m_nth_power) -
             pow(interval.minValue(), m_nth_power));
  } else {
    // Assume log10 type
    // Have to deal with the possibility that a user has entered 0 as a minimum
    double minValue = interval.minValue();
    if (minValue < LOG_ZERO_CUTOFF) {
      minValue = 1.0;
    }
    ratio = std::log10(value / minValue) /
            std::log10(interval.maxValue() / minValue);
  }
  return ratio;
}
예제 #8
0
/*!
  Map a value of a given interval into a rgb value

  \param interval Range for all values
  \param value Value to map into a rgb value
*/
QRgb QwtLinearColorMap::rgb(
    const QwtDoubleInterval &interval, double value) const
{
    const double width = interval.width();

    double ratio = 0.0;
    if ( width > 0.0 )
        ratio = (value - interval.minValue()) / width;

    return d_data->colorStops.rgb(d_data->mode, ratio);
}
예제 #9
0
/*!
  Check if an interval "contains" a value

  \param interval Interval
  \param value Value

  \sa QwtScaleArithmetic::compareEps()
*/
bool QwtScaleEngine::contains(
    const QwtDoubleInterval &interval, double value) const
{
    if (!interval.isValid() )
        return false;
    
    if ( QwtScaleArithmetic::compareEps(value, 
        interval.minValue(), interval.width()) < 0 )
    {
        return false;
    }

    if ( QwtScaleArithmetic::compareEps(value, 
        interval.maxValue(), interval.width()) > 0 )
    {
        return false;
    }

    return true;
}
예제 #10
0
/*!
  Map a value of a given interval into a rgb value

  \param interval Range for all values
  \param value Value to map into a rgb value
*/
QRgb LinearTransparentColorMap::rgb(
    const QwtDoubleInterval& interval, double value) const
{
    const double width = interval.width();

    double ratio = 0.0;
    if (width > 0.0)
        ratio = (value - interval.minValue()) / width;
    if (ratio < 0)
        return qRgba(0, 0, 0, 0);
    return d_data->colorStops.rgb(d_data->mode, ratio);
}
/*!
   \brief Calculate a scale division

   \param x1 First interval limit 
   \param x2 Second interval limit 
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.

   \sa QwtScaleEngine::stepSize, LogTimeScaleEngine::subDivide
*/
QwtScaleDiv LogTimeScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    interval = interval.limited(LOG_MIN, LOG_MAX);

    if (interval.width() <= 0 )
        return QwtScaleDiv();

    if (interval.maxValue() / interval.minValue() < 10.0)
    {
        // scale width is less than one decade -> build linear scale
    
        QwtLinearScaleEngine linearScaler;
        linearScaler.setAttributes(attributes());
        linearScaler.setReference(reference());
        linearScaler.setMargins(
                                #if (QWT_VERSION >= 0x050200)
				lowerMargin(), upperMargin()
				#else
				loMargin(), hiMargin()
				#endif
				);

        return linearScaler.divideScale(x1, x2, 
            maxMajSteps, maxMinSteps, stepSize);
    }

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 )
    {
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

        stepSize = divideInterval(log10(interval).width(), maxMajSteps);
        if ( stepSize < 1.0 )
            stepSize = 1.0; // major step must be >= 1 decade
    }

    QwtScaleDiv scaleDiv;
    if ( stepSize != 0.0 )
    {
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
        buildTicks(interval, stepSize, maxMinSteps, ticks);

        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
/*!
  Calculate the new scale interval of a plot axis

  \param axis Axis index ( see QwtPlot::AxisId )
  \param oldSize Previous size of the canvas
  \param newSize New size of the canvas

  \return Calculated new interval for the axis
*/
QwtDoubleInterval QwtPlotRescaler::expandScale( int axis,
    const QSize &oldSize, const QSize &newSize) const
{
    const QwtDoubleInterval oldInterval = interval(axis);

    QwtDoubleInterval expanded = oldInterval;
    switch(rescalePolicy())
    {
        case Fixed:
        {
            break; // do nothing
        }
        case Expanding:
        {
            if ( !oldSize.isEmpty() )
            {
                double width = oldInterval.width();
                if ( orientation(axis) == Qt::Horizontal )
                    width *= double(newSize.width()) / oldSize.width();
                else
                    width *= double(newSize.height()) / oldSize.height();

                expanded = expandInterval(oldInterval, 
                    width, expandingDirection(axis));
            }
            break;
        }
        case Fitting:
        {
            double dist = 0.0;
            for ( int ax = 0; ax < QwtPlot::axisCnt; ax++ )
            {
                const double d = pixelDist(ax, newSize);
                if ( d > dist )
                    dist = d;
            }
            if ( dist > 0.0 )
            {
                double width;
                if ( orientation(axis) == Qt::Horizontal )
                    width = newSize.width() * dist;
                else
                    width = newSize.height() * dist;

                expanded = expandInterval(intervalHint(axis), 
                    width, expandingDirection(axis));
            }
            break;
        }
    }

    return expanded;
}
예제 #13
0
/*!
   Build and return a color map of 256 colors

   The color table is needed for rendering indexed images in combination
   with using colorIndex().

   \param interval Range for the values
   \return A color table, that can be used for a QImage
*/
QwtColorTable QwtColorMap::colorTable(
    const QwtDoubleInterval &interval) const
{
    QwtColorTable table(256);

    if ( interval.isValid() ) {
        const double step = interval.width() / (table.size() - 1);
        for ( int i = 0; i < (int) table.size(); i++ )
            table[i] = rgb(interval, interval.minValue() + step * i);
    }

    return table;
}
예제 #14
0
void ColorMapEditor::updateColorMap()
{
  int rows = table->rowCount();
  QColor c_min = QColor(table->item(0, 1)->text());
  QColor c_max = QColor(table->item(rows - 1, 1)->text());
  QwtLinearColorMap map(c_min, c_max);
  for (int i = 1; i < rows-1; i++){
    QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);
    double val = (((DoubleSpinBox*)table->cellWidget(i, 0))->value() - min_val)/range.width();
    map.addColorStop (val, QColor(table->item(i, 1)->text()));
  }

  color_map = map;
  setScaledColors(scaleColorsBox->isChecked());
}
예제 #15
0
/*!
  \brief Map a value of a given interval into a alpha value

  alpha := (value - interval.minValue()) / interval.width();

  \param interval Range for all values
  \param value Value to map into a rgb value
  \return rgb value, with an alpha value
*/
QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
                           double value) const
{
    const double width = interval.width();
    if ( width >= 0.0 ) {
        const double ratio = (value - interval.minValue()) / width;
        int alpha = qRound(255 * ratio);
        if ( alpha < 0 )
            alpha = 0;
        if ( alpha > 255 )
            alpha = 255;

        return d_data->rgb | (alpha << 24);
    }
    return d_data->rgb;
}
예제 #16
0
QwtValueList QwtLinearScaleEngine::buildMajorTicks(
    const QwtDoubleInterval &interval, double stepSize) const
{
    int numTicks = qRound(interval.width() / stepSize) + 1;
    if ( numTicks > 10000 )
        numTicks = 10000;

    QwtValueList ticks;

    ticks += interval.minValue();
    for (int i = 1; i < numTicks - 1; i++)
        ticks += interval.minValue() + i * stepSize;
    ticks += interval.maxValue();

    return ticks;
}
예제 #17
0
void ColorMapEditor::insertLevel()
{
  int row = table->currentRow();
  DoubleSpinBox *sb = (DoubleSpinBox*)table->cellWidget(row, 0);
  if (!sb)
    return;

  double current_value = sb->value();
  double previous_value = min_val;
  sb = (DoubleSpinBox*)table->cellWidget(row - 1, 0);
  if (sb)
    previous_value = sb->value();

  double val = 0.5*(current_value + previous_value);
  QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);
  double mapped_val = (val - min_val)/range.width();

  QColor c = QColor(color_map.rgb(QwtDoubleInterval(0, 1), mapped_val));

  table->blockSignals(true);
  table->insertRow(row);

  sb = new DoubleSpinBox();
  sb->setLocale(d_locale);
  sb->setDecimals(d_precision);
  sb->setValue(val);
  sb->setRange(min_val, max_val);
  connect(sb, SIGNAL(valueChanged(double)), this, SLOT(updateColorMap()));
  connect(sb, SIGNAL(activated(DoubleSpinBox *)), this, SLOT(spinBoxActivated(DoubleSpinBox *)));
  table->setCellWidget(row, 0, sb);

  QTableWidgetItem *it = new QTableWidgetItem(c.name());
// Avoid compiler warning
//#ifdef Q_CC_MSVC
  it->setFlags(it->flags() & (~Qt::ItemIsEditable));
//#else
//  it->setFlags(!Qt::ItemIsEditable);
//#endif
  it->setBackground(QBrush(c));
  it->setForeground(QBrush(c));
  table->setItem(row, 1, it);
  table->blockSignals(false);

  enableButtons(table->currentRow());
  updateColorMap();
}
예제 #18
0
void ColorMapEditor::setColorMap(const QwtLinearColorMap& map)
{
  scaleColorsBox->setChecked(map.mode() == QwtLinearColorMap::ScaledColors);

  QwtArray <double> colors = map.colorStops();
  int rows = (int)colors.size();
  table->setRowCount(rows);
  table->blockSignals(true);

  QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);
  for (int i = 0; i < rows; i++){
    DoubleSpinBox *sb = new DoubleSpinBox();
    sb->setLocale(d_locale);
    sb->setDecimals(d_precision);
    sb->setValue(min_val + colors[i] * range.width());

    if (i == 0)
      sb->setRange(min_val, min_val);
    else if (i == rows -1)
      sb->setRange(max_val, max_val);
    else
      sb->setRange(min_val, max_val);

    connect(sb, SIGNAL(valueChanged(double)), this, SLOT(updateColorMap()));
    connect(sb, SIGNAL(activated(DoubleSpinBox *)), this, SLOT(spinBoxActivated(DoubleSpinBox *)));
    table->setCellWidget(i, 0, sb);

    QColor c = QColor(map.rgb(QwtDoubleInterval(0, 1), colors[i]));
    QTableWidgetItem *it = new QTableWidgetItem(c.name());
// Avoid compiler warning
//#ifdef Q_CC_MSVC
    it->setFlags(it->flags() & (~Qt::ItemIsEditable));
//#else
//    it->setFlags(!Qt::ItemIsEditable);
//#endif
    it->setBackground(QBrush(c));
    it->setForeground(QBrush(c));
    table->setItem(i, 1, it);
  }
  table->blockSignals(false);

  color_map = map;
}
예제 #19
0
/**
 * Compute a lookup table
 *
 * @param interval :: The interval of values of the RGB component for
 * the table to cover
 */
QVector<QRgb>
MantidColorMap::colorTable(const QwtDoubleInterval &interval) const {
  // Swicth to linear scaling when computing the lookup table
  GraphOptions::ScaleType current_type = m_scale_type;
  m_scale_type = GraphOptions::Linear;

  short table_size = (m_num_colors > 1) ? m_num_colors : 2;
  QVector<QRgb> rgbtable(table_size + 1);
  if (interval.isValid()) {
    const double step = interval.width() / table_size;
    for (short i = 0; i < table_size; ++i) {
      rgbtable[i + 1] = rgb(interval, interval.minValue() + step * i);
    }
    // Special NAN at index 0
    rgbtable[0] = rgb(interval, m_nan);
  }

  // Restore scaling type
  m_scale_type = current_type;
  return rgbtable;
}
예제 #20
0
/*!
  Map a value of a given interval into a color index, between 0 and 255

  \param interval Range for all values
  \param value Value to map into a color index
*/
unsigned char QwtLinearColorMap::colorIndex(
    const QwtDoubleInterval &interval, double value) const
{
    const double width = interval.width();

    if ( width <= 0.0 || value <= interval.minValue() )
        return 0;

    if ( value >= interval.maxValue() )
        return (unsigned char)255;

    const double ratio = (value - interval.minValue()) / width;

    unsigned char index;
    if ( d_data->mode == FixedColors )
        index = (unsigned char)(ratio * 255); // always floor
    else
        index = (unsigned char)qRound(ratio * 255);

    return index;
}
/*!
   \brief Calculate a scale division

   \param x1 First interval limit
   \param x2 Second interval limit
   \param maxMajSteps Maximum for the number of major steps
   \param maxMinSteps Maximum number of minor steps
   \param stepSize Step size. If stepSize == 0, the scaleEngine
                   calculates one.
*/
QwtScaleDiv Log2ScaleEngine::divideScale(double x1, double x2,
    int maxMajSteps, int maxMinSteps, double stepSize) const
{
    QwtDoubleInterval interval = QwtDoubleInterval(x1, x2).normalized();
    interval = interval.limited(LOG_MIN, LOG_MAX);

    if (interval.width() <= 0 )
        return QwtScaleDiv();

    if (interval.maxValue() / interval.minValue() < 2){
        // scale width is less than 2 -> build linear scale
        QwtLinearScaleEngine linearScaler;
        linearScaler.setAttributes(attributes());
        linearScaler.setReference(reference());
        linearScaler.setMargins(lowerMargin(), upperMargin());

        return linearScaler.divideScale(x1, x2,
            maxMajSteps, maxMinSteps, stepSize);
    }

    stepSize = qwtAbs(stepSize);
    if ( stepSize == 0.0 ){
        if ( maxMajSteps < 1 )
            maxMajSteps = 1;

		stepSize = ceil(log2(interval).width()/double(maxMajSteps));
    }

    QwtScaleDiv scaleDiv;
    if ( stepSize != 0.0 ){
        QwtValueList ticks[QwtScaleDiv::NTickTypes];
		buildTicks(interval, stepSize, maxMinSteps, ticks);
        scaleDiv = QwtScaleDiv(interval, ticks);
    }

    if ( x1 > x2 )
        scaleDiv.invert();

    return scaleDiv;
}
/*! 
  Expand the interval

  \param interval Interval to be expanded
  \param width Distance to be added to the interval
  \param direction Direction of the expand operation

  \return Expanded interval
*/
QwtDoubleInterval QwtPlotRescaler::expandInterval(
    const QwtDoubleInterval &interval, double width,    
    ExpandingDirection direction) const
{
    QwtDoubleInterval expanded = interval;

    switch(direction)
    {
        case ExpandUp:
            expanded.setMinValue(interval.minValue());
            expanded.setMaxValue(interval.minValue() + width);
            break;
        case ExpandDown:
            expanded.setMaxValue(interval.maxValue());
            expanded.setMinValue(interval.maxValue() - width);
            break;
        case ExpandBoth:
        default:
            expanded.setMinValue(interval.minValue() +
                interval.width() / 2.0 - width / 2.0);
            expanded.setMaxValue(expanded.minValue() + width);
    }
    return expanded;
}
void ColorMapEditor::validateLevel(int row, int col)
{
if (col)
	return;

if (row == 0 || row == table->rowCount() - 1)
	{
	QMessageBox::critical(this, tr("Input Error"), tr("Sorry, you cannot edit this value!"));
	table->blockSignals(true);
	if (!row)
		table->item(0, 0)->setText(QString::number(min_val));
	else
		table->item(row, 0)->setText(QString::number(max_val));
	table->blockSignals(false);
	return;
	}

bool user_input_error = false;
QString s = table->item(row, 0)->text().remove("-").remove(".").remove(",").remove("+");
if (s.isEmpty() || s.contains(QRegExp("\\D")))
	{
	QMessageBox::critical(this, tr("Input Error"), tr("Please enter a valid color level value!"));
	user_input_error = true;
	}

QwtDoubleInterval range = QwtDoubleInterval(min_val, max_val);
double val = table->item(row, 0)->text().replace(",", ".").toDouble();
if (!range.contains (val) || user_input_error)
	{
	QwtArray<double> colors = color_map.colorStops();	
	val = min_val + colors[row] * range.width();
	table->blockSignals(true);
	table->item(row, 0)->setText(QString::number(val));
	table->blockSignals(false);
	}
}