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

Message ListMessage List     Post MessagePost Message

  Divide X-axis values
Posted by winch20010 on Dec-11-2009 15:26
Attachments:
Hello,

I create some charts for my home automation system.
the goal is to draw datas retrieve each 15min (from today and yesterday)

Example :
date            hour     value
2009-12-08  10:00   3
2009-12-08  10:15   6
2009-12-08  10:30   2
...


the problem is it seems the chart only show 1hour data but the 15min datas.
I sent the jpg file.


the script :

....
Data perl part
....
snipp

# Add a title to the y axis
$c->yAxis()->setTitle("Intensite");

# Set the labels on the x axis.
$c->xAxis()->setLabels($labels);

# Display 1 out of 3 labels on the x-axis.
$c->xAxis()->setLabelStep(3);

# Add a title to the x axis
$c->xAxis()->setTitle($date);

# Add a line layer to the chart
my $layer = $c->addLineLayer2();

# Set the default line width to 2 pixels
$layer->setLineWidth(2);


$c->xAxis->setLinearScale(0, 24, 1);
$c->xAxis->setLabelFormat("{value}:00");

$layer = $c->addLineLayer($data0, 0xff0000, "Today");
$layer->setXData($labels);

# Add the three data sets to the line layer. For demo purpose, we use a dash line
# color for the last line
$layer->addDataSet($data1, 0x008800, "Yesterday");


# Output the chart
$c->makeChart("multiline.jpg")
multiline.jpg

  Re: Divide X-axis values
Posted by Peter Kwan on Dec-11-2009 17:31
Hi winch20010,

Note that "10:00" is not a date or a time. It is a text string. If the x-coordinates are not date or time or numbers, then you cannot use it in setXData.

In your case, my guess is that $labels just contains text strings. So the code should be:

# Set the labels on the x axis.
$c->xAxis()->setLabels($labels);

# Display 1 out of 4 labels on the x-axis.
$c->xAxis()->setLabelStep(4);

# Add a title to the x axis
$c->xAxis()->setTitle($date);

# Add a line layer to the chart
my $layer = $c->addLineLayer2();

# Set the default line width to 2 pixels
$layer->setLineWidth(2);

$layer = $c->addLineLayer($data0, 0xff0000, "Today");

# Add the three data sets to the line layer. For demo purpose, we use a dash line
# color for the last line
$layer->addDataSet($data1, 0x008800, "Yesterday");

Alternatively, if you would like to set the x-axis scale to be number from 0 to 24, your x-coordinates must also be numbers to be consistent with the axis scale. For example, instead of "10:00", you should use 10. Instead of "10:30", you should use 10.5 (10.5 hours). In this case, the code is:

# Add a title to the y axis
$c->yAxis()->setTitle("Intensite");

# Add a title to the x axis
$c->xAxis()->setTitle($date);

# Add a line layer to the chart
my $layer = $c->addLineLayer2();

# Set the default line width to 2 pixels
$layer->setLineWidth(2);

$c->xAxis->setLinearScale(0, 24, 1);
$c->xAxis->setLabelFormat("{value}:00");

$layer = $c->addLineLayer($data0, 0xff0000, "Today");
$layer->setXData($myXCoors);

# Add the three data sets to the line layer. For demo purpose, we use a dash line
# color for the last line
$layer->addDataSet($data1, 0x008800, "Yesterday");

Hope this can help.

Regards
Peter Kwan

  Re: Divide X-axis values
Posted by winch20010 on Dec-11-2009 19:00
Thanks a lot Peter as usual. so amazing to see you are so active !!

with the first solution it works well for me, except if I have some gaps in the values, it won't be shown and even shift all the values.

The second one is more difficult for me to put in place.


Cheers

  Re: Divide X-axis values
Posted by Peter Kwan on Dec-12-2009 00:35
Hi winch20010,

Actually, the second method should not be more difficult than the first method. In terms of the charting part, both methods are simplier than your original code. The only differences are the type of data you pass to the code. If your data are from a database, you may not need to write any additional code at all. You may simply modify the SQL query to retrieve the data required by the code.

I am not sure exactly what are the $labels in your code. If they are text strings of the format "hh:nn", and you do not want to modify your SQL statement (or your data are not from SQL), you can convert them to the hours representation in a few lines of PHP code. For example:

for ($i = 0; $i < count($labels); ++$i) {
    list($hour, $minute) = explode(":", $labels[$i]);
    $labels[$i] = ((int)$hour) + ((int)$minute) / 60.0;
}

Hope this can help.

Regards
Peter Kwan

  Re: Divide X-axis values
Posted by winch20010 on Dec-12-2009 17:23
It works like a charm with the 1st method.
I tried to put in place the second method, but no luck.

here the details :
I have a csv file like :
day, hour, value
2009/12/07,00:00,20
2009/12/07,00:15,25
...
2009/12/08,10:00,20
2009/12/08,10:15,25
2009/12/08,10:30,13
...

so a value each 15minutes (but some values can missing)

I modified the "hour" field to be 10.25 instead of 10:15, etc, as you mentionned.
so the "hour" field is now an value and no more a string.


I would like to have a x-axis as a scale between 0-24h and automaticly put the values to the right time x-xaxis value depending of their "hour" field.
by this way, if some datas are missing in the csv file, they will be ignore, with no inconsistencies in the graph.


I hope I was more clear :)

  Re: Divide X-axis values
Posted by winch20010 on Dec-14-2009 14:39
Attachments:
Re,

I update my message with a screenshot of what exactly I want to make with chart director.
I still try to do it, but I fail everytime.  quiet tricky...
thanks again.
chart.jpg

  Re: Divide X-axis values
Posted by Peter Kwan on Dec-14-2009 17:01
Hi winch20010,

In your attached chart, you have gaps, representing as empty cells in the original Excel spreadsheet.

For ChartDirector, the empty cells can be represented using the constant $perlchartdir::NoValue.

For example, the data x2 can be represented as:

$x2 = [12, $perlChartDirector::NoValue, 33, 43, $perlchartdir::NoValue, 15, 53, 12, ....];

So for your case, you can continue to use the first method. I am not sure how the data are represented in your CSV file. In general, when you code reads in the data, if it detects that an entry is missing, it should append $perlChartDirector::NoValue to the data array to represent the missing value.

See the sample code "Missing Data Points" for an example.

Sorry about the previous code I suggest. The code is written in PHP. After I read your code again today, I realized it is in Perl. So the PHP code will not work directly unless you translate it to Perl. Anyway, as you can use the first method, so the code is not needed.

Hope this can help.

Regards
Peter Kwan

  Re: Divide X-axis values
Posted by winch20010 on Dec-14-2009 17:42
Ok, so I will do like this.
I was not really convinced by this solution (use NoValue), because the datas (hour-minutes) are randomly reported.
The unix job was :
every 15min, run the script to get datas. By this way, the problem is we can have a shift like ->   ..., 10:15, 10:31 (instead of 10:30), 10:45, 11:00, ...   then even with NoValue, it's too difficult to have a consistent graph.

I will update the Unix job like :
run the script at xx:00, xx:15, xx:30, xx:45 to be sure the result will be more consistent.
I can then use the NoValue here.



I hope in a future version we will be able to create a fixed x-axis between 2 values, then all datas between these values will automaticly be inserted at the right place :)
At the beginning, I thought
$c->xAxis->setLinearScale(0, 24, 1);
was made for that.




Thanks for the help and your clarifications. it's very appreciate.

  Re: Divide X-axis values
Posted by Peter Kwan on Dec-15-2009 01:28
Hi winch20010,

Actually, I suggest the first method and to use NoValue, because you mention the Excel chart is "exactly what you want to make". If your actual chart is different (say, the data are "randomly reported"), you can use the second method.

One key feature in the Excel chart is there are gaps in the lines. (The blue line is discontinuous.) If this is "exactly what you want to make", you would need to tell ChartDirector where is the missing point. It is impossible to know where are the missing points for "randomly reported" data.

For example, if the data are reported to be at (8:01, 8:14, 8:27, 8:44, 8:52), where are the gaps in the line, if any? It is not possible to tell.

If you really need the gaps, the method to inform ChartDirector where are the gaps is to insert NoValue points. If you do not need the gaps, you can still plot unevenly spaced points using the second method.

If you cannot make it work, please include your data (the CSV file) and your code, and also clarify exact what you need. I will modify the code to make it work.

Regards
Peter Kwan

  Re: Divide X-axis values
Posted by winch20010 on Dec-15-2009 02:13
Attachments:
Hello,

Here the Csv. it represents my Electricity meter at home


so, the goal is to make:
- a graph for Today (2009-12-11) between 0 and 24h who represents "IntensityRealTime" value
- an another graph for yesterday (2009-12-10) also between 0 and 24h who represents also "IntensityRealTime" value

They must be in the same scale (0-24h) to compare the values at the same moment.

These 2 graphs must be similar to the xls file I sent before.


Cheers.
teleinfo.csv
teleinfo.csv

18.58 Kb

  Re: Divide X-axis values
Posted by Peter Kwan on Dec-15-2009 17:48
Attachments:
Hi winch20010,

I have attached an example based on the Simple Line Chart sample code for your reference. As you can see, the charting code is very simple. The majority if the code is used to process the CSV format file.

Hope this can help.

Regards
Peter Kwan
simpleline.png
test.pl
#!/usr/bin/perl
use perlchartdir;

open (F, "teleinfo.csv");
$line = <F>;
while ($line = <F>) {
  ($dummy, $date, $time, $dummy, $dummy, $dummy, $dummy, $dummy, $dummy, $value, 
    $dummy, $dummy, $dummy, $dummy, $dummy) = split("','", $line);
  ($hh, $nn, $ss) = split(':', $time);
  $time = $hh + $nn / 60.0 + $ss / 3600.0;
  if ($date eq "2009-12-10") { 
  	push @timeStamp0, $time;
  	push @data0, $value;
  } else {
   	push @timeStamp1, $time;
  	push @data1, $value;
  }
}
close (F);

$c = new XYChart(600, 300);
$c->setPlotArea(50, 40, 520, 220);

$layer = $c->addLineLayer(\\@data0);
$layer->setXData(\\@timeStamp0);

$layer = $c->addLineLayer(\\@data1);
$layer->setXData(\\@timeStamp1);

$c->xAxis()->setLinearScale(0, 24, 1);

$c->makeChart("simpleline.png")

  Re: Divide X-axis values
Posted by winch20010 on Dec-16-2009 03:17
ah :)   thank you so much.
It works perfectly now.
I didn't convert correctly the $time, it's probably why my charts were not correct.

Cheers !