Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PChart linear chart image quality

I am using PChart to create linear charts. Everything goes well beside the quality of the actual lines drawn.

Of course, antialiasing is not turned off, and even explicitly turned on.

Here is an example of the actual image, which looks quite ugly with all these steps.

enter image description here

Is there a way to make the lines drawn smoother, without stepping?

The code used:

public function linearTwoAxis($data, $fileName, $startColor = 0)
{
    $pData = new \pData();

    $i = 0;
    foreach ($data as $key => $row)
    {
        $serie = $this->translator->trans("pages.reportDefault.$key");
        $pData->addPoints($row, $serie);
        $pData->setSerieOnAxis($serie, $i);
        $pData->setSerieWeight($serie, 1);
        $pData->setAxisName($i, $serie);
        $pData->setPalette($serie, $this->colors[$startColor++]);
        $pData->setAxisDisplay($i, AXIS_FORMAT_METRIC);
        $i++;
    }
    $monthNames = array_keys($row);

    $pData->setAxisPosition(1, AXIS_POSITION_RIGHT);
    $pData->addPoints($monthNames, "Labels");
    $pData->setAbscissa("Labels");

    $pChart = new \pImage(750, 200, $pData);

    $pChart->setFontProperties(array(
        "FontName" => $this->fonts_dir . "arial.ttf",
        "FontSize" => 8)
    );

    $pChart->setGraphArea(50, 10, 700, 150);
    $pChart->Antialias = TRUE;
    $pChart->drawScale(["Mode"  => SCALE_MODE_START0]);
    $pChart->drawLineChart();
    $pChart->drawLegend(325,180,array("Style"=>LEGEND_BOX,"Mode"=>LEGEND_HORIZONTAL, "BoxWidth"=>30,"Family"=>LEGEND_FAMILY_LINE,"Alpha" => 0));

    $pChart->render($this->target_dir . $fileName);

    return $this->target_dirname . $fileName;
}
like image 893
Your Common Sense Avatar asked Sep 27 '16 13:09

Your Common Sense


1 Answers

If nothing else helps draw the chart much larger and then scale down the resulting image with ImageMagick. This is a last resort solution which has an obvious additional computation cost.

That's an example line:

convert chart.png -resize 750×200 chart.jpg

If the original image is twice as large (by simply doubling both dimensions you have in your code) a resize like this would collapse four pixels into one, smoothing out jaggies on five levels (0%, 25%, 50%, 75%, 100%). If you draw the image even larger you may switch off anti aliasing when drawing the lines, because the resizing will smooth out everything anyways.

Fonts and readability may become a problem, so maybe you want to draw two images:

  • just the lines on a larger scale;
  • the remaining legend/rulers and such on the original scale.

After resizing the line image, you then have to combine both images by overlapping them into one single image. This can be done with ImageMagick, too.

like image 108
pid Avatar answered Sep 20 '22 06:09

pid