ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Intelligent text wrapping?
Posted by Zannie on Apr-04-2009 09:11
Hi Peter,

I am trying to implement a generic method of displaying different messages in all the charts in our system.  Here is a snippet of my PHP:

  //---------------------------------------------------------------------------------------------
  protected function add_text($text, $x, $y, $width, $height) {
    $text_box = $this->cd_chart->addText($x, $y, $text,'',18,Chart_Colors::LIGHT_GRAY,Center);
    $text_box->setSize($width, $height);
    $text_box->setMaxWidth($width);
  }

  //---------------------------------------------------------------------------------------------
  protected function add_full_chart_text($text) {
    $this->add_text($text,
                    $this->cd_chart_plot_params['x'],  // coordinates of plot area
                    $this->cd_chart_plot_params['y'],
                    $this->cd_chart_plot_params['width'],
                    $this->cd_chart_plot_params['height']);
  }


This works pretty well, but depending on the particular size of the chart and the length of the text, the wrapping can look a little odd.  For instance, it might wrap like this:

The chart has encountered an
error.

Is there any way to get ChartDirector's wrapping to try to make lines of close to equal length?  For instance, either of these would be preferable, especially the second:

The chart has encountered
an error.

The chart has
encountered an error.


Secondly, is there any way for me to programmatically determine if a message is simply not going to fit, so that I can reduce the font size until it does?

Thanks so much.

  Re: Intelligent text wrapping?
Posted by Zannie on Apr-04-2009 09:13
As a final note, this code is called after layout(), in case that is useful information.

  Re: Intelligent text wrapping?
Posted by Peter Kwan on Apr-04-2009 15:03
Hi Zannie,

Unluckily, the method you want the text to wrap is not implemented in ChartDirector. It must be noted that the method you want is not implemented in common word processor or HTML either. All these programs would wrap the text the same way as ChartDirector.

You can programmatically get the length of the text using:

$text_box = $this->cd_chart->addText($x, $y, $text,'',18,Chart_Colors::LIGHT_GRAY,Center);
$width = $text_box->getWidth();

You can change change the font size (using $text_box->setFontSize), and get the width again (possibly in a loop) until it fits (the width is less than the maximum width allowed).

Hope this can help.

Regards
Peter Kwan

  Re: Intelligent text wrapping?
Posted by Zannie on Apr-07-2009 01:02
Thanks, Peter.  I think I can work with that.  (And you're right, my magic function isn't implemented in those technologies either, but hope springs eternal.)

  Re: Intelligent text wrapping?
Posted by Zannie on Apr-07-2009 02:20
Here's what I came up with, for posterity's sake.  No guarantees, this hasn't been through QA yet.  :)

  //---------------------------------------------------------------------------------------------
  protected function add_full_chart_text($text) {
    $font = '';
    $font_size = 18;
    $plot_width = $this->cd_chart_plot_params['width'];
    $plot_height = $this->cd_chart_plot_params['height'];

    $text_box = $this->cd_chart->addText($this->cd_chart_plot_params['x'],
                                         $this->cd_chart_plot_params['y'],
                                         $text,
                                         $font,
                                         $font_size,
                                         Chart_Colors::LIGHT_GRAY,
                                         Center);

    // ZA 4/2009:
    // The text might be too wide and need to be wrapped.  ChartDirector can do this
    // with $text_box->setMaxWidth($width) but the placement of breaks can be undesireable.

    // Step 1:
    // Change spaces to newlines at roughly equidistant intervals, using heuristics.
    $width = $text_box->getWidth();
    if ($width > $plot_width) {
      $num_breaks_needed = ceil($width/$plot_width);
      $line_length = floor(strlen($text)/$num_breaks_needed);

      $new_text = '';
      while (strlen($text) > 0 ) {
        if ($line_length > strlen($text)) {
          $new_text .= $text;
          break;
        }
        else {
          $break_pos = strpos($text, ' ', $line_length);
          if ($break_pos === false) {
            $new_text .= $text;
            break;
          }

          $new_text .= substr($text, 0, $break_pos)."\n";
          $text = substr($text, $break_pos+1);
        }
      }
      $text_box->setText($new_text);
    }

    // Step 2:
    // The heuristics are very often going to produce lines that are still too wide, and by breaking the
    // text into multiple lines we may have made it too tall.  Therefore, reduce the font size until the
    // $text_box can fit inside the plot area.
    while (($text_box->getWidth() > $plot_width || $text_box->getHeight() > $plot_height) && $font_size > 1) {
      $font_size -= 1;
      $text_box->setFontSize($font_size);
    }

    // Step 3:
    // Match the size of the $text_box to the size of the plot area so the text displays in the center of the chart.
    $text_box->setSize($plot_width, $plot_height);

  Re: Intelligent text wrapping?
Posted by Peter Kwan on Apr-07-2009 14:42
Hi Zannie,

Thanks for a lot for contributing your useful function to this forum. I am sure it will help a lot of people. It will help us a lot too in supporting our customers too, as we can point to your message as an example on how dynamic text sizing can be achieved.

Regards
Peter Kwan