Jump to content

How to get even amounts of data in a two column text frame


Ryan_B

Recommended Posts

I have built a pie chart using an external data file. I've opted to create my own legend rather than use the built in FusionPro legend. Similar to the built in legend, I'm using color coded diamonds to show the ten different spending categories.

Here is my code:

var pieLegend = '';
var counter = -1;

if(Field("Agriculture Total") != 0){counter++;}
if(Field("Clothing Total") != 0){counter++;}
if(Field("Hardware Total") != 0){counter++;}
if(Field("Livestock/Pet Total") != 0){counter++;}
if(Field("Seasonal Total") != 0){counter++;}
if(Field("Special Order") != 0){counter++;}
if(Field("Toy/Gift") != 0){counter++;}
if(Field("Fencing/Equip") != 0){counter++;}
if(Field("Truck/Trailer") != 0){counter++;}
if(Field("Misc Total") != 0){counter++;}

var colors = ["<color name=Green>", "<color name=Orange>", "<color name=Blue>", "<color name=Pink>", "<color name=Yellow>", "<color name=SeaFoam>", "<color name=Red>", "<color name=Lavender>", "<color name=Magenta>", "<color name=Tan>"];

if(Field("Agriculture Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12"><leading newsize=80>'+"♦ "+'<z newsize ="7"><color name=Black>'+"Agriculture Total - $"+Field("Agriculture Total")+'<br>';
   counter--;
}
if(Field("Clothing Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Clothing Total - $"+Field("Clothing Total")+'<br>';
   counter--
}
if(Field("Hardware Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Hardware Total - $"+Field("Hardware Total")+'<br>';
   counter--
}
if(Field("Livestock/Pet Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Livestock/Pet Total - $"+Field("Livestock/Pet Total")+'<br>';
   counter--
}
if(Field("Seasonal Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Seasonal Total - $"+Field("Seasonal Total")+'<br>';
   counter--
}
if(Field("Special Order") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Special Order Total - $"+Field("Special Order")+'<br>';
   counter--
}
if(Field("Toy/Gift") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Toy/Gift Total - "+'<color name=Black>'+"$"+Field("Toy/Gift")+'<br>';
   counter--
}
if(Field("Fencing/Equip") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Fencing/Equip Total - "+'<color name=Black>'+"$"+Field("Fencing/Equip")+'<br>';
   counter--
}
if(Field("Truck/Trailer") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Truck/Trailer Total - "+'<color name=Black>'+"$"+Field("Truck/Trailer")+'<br>';
   counter--
}
if(Field("Misc Total") != "0")
{
   pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Misc Total - "+'<color name=Black>'+"$"+Field("Misc Total")+'<br>';
   counter--
}

return pieLegend;

 

This works well and matches the correct color to the correct pie slice:

1.PNG.b394e9809a90598f6eb017b8af45cd6d.PNG

 

 

What about however, when a customer doesn't spend money in all ten categories? Let's say a customer only spends money in five categories. The data no longer gets split up into my two columns within the text frame, like so:

2.PNG.93f3d20414a13a2b022360d3e660da9d.PNG

 

However, while composing a different record that also only spent in five categories, the data does get split up, like so:

3.PNG.065b53862d2159a6b1fd7d697620ee0c.PNG

The difference between the two, aside from the data splitting, are the categories the customer spent money in.

 

Question #1:

Why would these records be composing differently?

 

Question #2:

Why on the record that did split the data, appear to have line breaks inserted in between the data?

 

Question #3:

What code do I need to write to make the data (no matter how many categories the customer spent in) split into even columns?

 

 

I have done a business card in the past that had x amount of bullet points that the user could enter. It was inside a two column text frame just as this legend is, and I was able to successfully split the data evenly in the two columns using this bit of code:

return '<page destination="topofcolumn" balance="true" />';

 

Yet when I try to reuse that code for the legend, I get some inconsistent results:

This is the same pie chart shown above (the second one). You can see that it is splitting up the data as desired.

4.PNG.36d73ec6e42da579598e88ddd6f1f2a2.PNG

 

This is the first pie chart from above. You can see that some of the data is getting duplicated.

5.PNG.b6e2697761b8bec4c743b923024c2f0f.PNG

 

Question #4:

Why does it work as expected on the one pie chart, and not the other?

 

Question #5:

Why is some of the data getting duplicated on the pie chart where the customer spent in all ten categories?

 

Question #6:

How do I need to adjust my code to get this to work?

 

Question #7:

Once the snippet of code is corrected (if need be), do I place it after my return pieLegend like so:

return pieLegend+'<page destination="topofcolumn" balance="true" />';

or do I place it in the text frame after my custom pie legend like so: <<Pie Legend>><<Even Columns>>

 

I know this is quite a bit to go through, and I've asked several questions here. That being said, thank you to anyone in advance for taking the time to look at this. I've been trying to figure this out for some time now, and am getting tired of beating my head against the wall.

Link to comment
Share on other sites

Question #1:

Why would these records be composing differently?

That is difficult to say for certain but as you mentioned, The categories are different and the values of those categories are different. So I believe part of it to be because of the way FP is trying to copyfit those unique flows of text. Additionally, I believe the bigger culprit to be the fact that you have "Use legacy line leading" enabled in your global paragraph settings (Paragraph... > Global Settings...). I honestly am not sure what that setting controls but in my experience its status is usually to blame for any wild shifts in leading in a template. If you don't need it, I'd recommend turning it off to see if that helps.

 

Question #2:

Why on the record that did split the data, appear to have line breaks inserted in between the data?

In your code you only apply a leading tag to the "Agriculture Total" line. You never close that leading tag so if the "Agriculture Total" is present in the legend, the leading is applied to all line items. What you're seeing in that particular graph is the auto-leading (120% font size) being applied in the absence of an absolute leading.

 

// ...
if(Field("Agriculture Total") != "0")
 {
     pieLegend += colors[counter]+'<z newsize="12">[color="Red"]<leading newsize=80>[/color]'+"♦ "+'<z newsize ="7"><color name=Black>'+"Agriculture Total - $"+Field("Agriculture Total")+'<br>';
     counter--;
 }
 if(Field("Clothing Total") != "0")
 {
     pieLegend += colors[counter]+'<z newsize="12">'+"♦ "+'<z newsize ="7"><color name=Black>'+"Clothing Total - $"+Field("Clothing Total")+'<br>';
     counter--
 }
// ...

 

Question #3:

What code do I need to write to make the data (no matter how many categories the customer spent in) split into even columns?

 

I have done a business card in the past that had x amount of bullet points that the user could enter. It was inside a two column text frame just as this legend is, and I was able to successfully split the data evenly in the two columns using this bit of code:

return '<page destination="topofcolumn" balance="true" />';

 

Yet when I try to reuse that code for the legend, I get some inconsistent results

That's a page layout tag. I can't say I'm familiar with it, personally, but I don't think that's the tag you want to be using for this. The paragraph tag has the same attribute and will allow you to work within the context of the paragraph.

 

 

Question #4:

Why does it work as expected on the one pie chart, and not the other?

Again, it's hard to say. I would refer you to my answer to your first question.

 

Question #5:

Why is some of the data getting duplicated on the pie chart where the customer spent in all ten categories?

I have seen legacy line leading cause this issue before.

 

Question #7:

Once the snippet of code is corrected (if need be), do I place it after my return pieLegend like so:

return pieLegend+'<page destination="topofcolumn" balance="true" />';

or do I place it in the text frame after my custom pie legend like so: <<Pie Legend>><<Even Columns>>

I hope you aren't OCD because I'm answering this one out of sequential order. As I mentioned before, I believe you want to use the paragraph tag (<p>) in lieu of the page tag so I would remove the "Even Columns" rule (page tag) all together. Though putting it at the end would likely cause some copyfitting issues.

 

Question #6:

How do I need to adjust my code to get this to work?

I'm not sure if I've mentioned this yet or not, but I first turn off legacy line leading.Then I would remove the "Even columns" rule. Then, if you want to adjust the leading, I'd do it in the paragraph settings of the text editor – an absolute leading of 8pt is the equivalent to the leading you're setting with tags in your code.

 

Speaking of your code, with every addition of a legend key, you append a break tag (<br>). There's nothing wrong with that, you just want to clean up that string before you return it so that you don't have unnecessary carriage returns taking up space in your text flow when it comes time to copy fit or balance the columns. You can clean that up pretty simply by just removing any break tag at the end of the string:

return pieLegend[color="red"].replace(/<br>$/,'')[/color];

 

I think you can save yourself a lot of repetition by putting your field names into an array, using the map method to tag them if the field is not equal to 0, and using the filter method to remove any empty keys. From there you have an array with all of your populated keys tagged appropriately which you can use to determine how many fields you'll need in each column by dividing the length in half and using Math.ceil to round up. Once you know where to split the array, you can use the splice method to get two arrays (left/right column), joining the elements of each with a break tag and finally joining the two columns with a paragraph tag that forces the second column into position:

var marker = '♦';
var colors = ["Green", "Orange", "Blue", "Pink", "Yellow", "SeaFoam", "Red", "Lavender", "Magenta", "Tan"];
var legend = [
   "Agriculture Total",
   "Clothing Total",
   "Hardware Total",
   "Livestock/Pet Total",
   "Seasonal Total",
   "Special Order",
   "Toy/Gift",
   "Fencing/Equip",
   "Truck/Trailer",
   "Misc Total"
]
.map(function (field) {
   return StringToNumber(Field(field)) ? 
   '<span pointsize="12" color="' + colors.shift() + '">' + marker + '</span> ' + 
   field.replace(' Total', '') + ' Total - $' + Field(field) : '';
})
.filter(String);

var left = legend.splice(0, Math.ceil(legend.length / 2));
return [ left, legend ]
   .map(function(s) { 
       return s.join('<br>');
   })
   .filter(String)
   .join('<p verticalstart=topofcolumn>');

 

Or the more compact version of the same code:

var marker = '♦';
var colors = ["Green", "Orange", "Blue", "Pink", "Yellow", "SeaFoam", "Red", "Lavender", "Magenta", "Tan"];
var legend = ["Agriculture Total", "Clothing Total", "Hardware Total", "Livestock/Pet Total", "Seasonal Total", "Special Order", "Toy/Gift", "Fencing/Equip", "Truck/Trailer", "Misc Total"].map(function (field) { return StringToNumber(Field(field)) ? '<span pointsize="12" color="' + colors.shift() + '">' + marker + '</span> ' + field.replace(' Total', '') + ' Total - $' + Field(field) : '';}).filter(String).join('<br>');

var left = legend.splice(0, Math.ceil(legend.length / 2));
return [ left, legend ].map(function(s) { return s.join('<br>'); }).filter(String).join('<p verticalstart=topofcolumn>');

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...