Expressive Forms – Part 4

Programmer

Previously, I talked through setting up a calculator form. This time, it’s a menu form. And, I’ll tell you where to get xf_form.js (free) for the helper routines.

A menu consists of several buttons. Each button links to a webpage, except those few buttons whose task it is to expand or collapse the menu. Since there is no submit button, this wouldn’t need to be a form. Yet, making it a form with readonly input fields, means that you have several less divs on your webpage. And I’m always grateful to have fewer divs to have to tell apart.

So, let’s make it a form. As with all the forms I’ve presented, there’s no action or method on the form. The form has an id, and it has an onsubmit attribute. For the menu, onsubmit is not really needed. Each button has the type of “button”. But, just in case the browser says to itself, there must be some onsubmit button, I added onsubmit=”event.preventDefault()”. This keeps the form from ending up with a blank menu.

You can go ahead and set up your menu buttons. If you want emoji on your buttons, my x_press.js library has several which are appropriate for menus. To use the home emoji, just enter &menu_home;. x_press() will interpret it for you. However, since your menu will be on every page, you’ll probably write it as a javascript function. If you do that, you’ll need to change &menu_home; to %menu_home; and call x_press a little differently. Or, you can just go to Emojipedia and copy-paste the emoji from there. xf_form.js relies on x_press.js, so you’ll be adding them both to your <head>. I’ll point the way at the end of this article.

xf_form.js helps with the expand / collapse menu buttons. These use the onclick event, rather than an <a href=…>. Each button has a data-menulevel attribute. I made the first level 0, then 1, then 2. But these routines allow you to assign whatever levels you want. You could start with 10, then 9. You don’t need to go in order, but why confuse yourself.

So, on my menu, all permanent buttons have data-menulevel=”0″. One of those permanent buttons is the menu button. This used to be a triple bar, now it’s a triple dot, as that takes less room. The menu button, expands the menu by opening menu level 1. The menu button also closes menu level 1 when it’s open. So, the menu button toggles menu level 1.

My menu has 3 levels (0, 1, and 2), so the onclick for the menu button is onclick=”xf_menu_close(‘menuform’,[2]);xf_menu_toggle(‘menuform’,[1])”. Close menu level 2 for form with id=”menuform”, then toggle menu level 1. There’s also xf_menu_open. These change the style visibility between visible and hidden.

For instructions on how to use my x_press.js and xf_form.js libraries, go to my Really Useful Javascript webpage. These libraries are light-weight, so they won’t slow down your site. Just keep in mind, that I change these libraries at will. Mostly I add new functions. But sometimes I have to revamp an existing function. And if you’re using that function, it may no longer work. So, contact me from my website to be notified of any changes I make. And, if enough people sign up, I may create new functions, rather than revamping existing ones. That way, the existing ones will still work. Yet, there are times when Google forces me to rewrite functions and not leave the old ones. So, sign up to stay informed. I promise I won’t spam you.

Expressive Forms – Part 3

Programmer

Previously, I explained how to create a contact form. In this part, I’ll explain how to create a calculator form.

In order to evaluate a math equation, you first have to parse it. Then you have to evaluate portions of the equation in the correct order. There are javascript libraries which will evaluate equations for you. I looked at 5 or 6 of those. Not too hard to implement, however, you have to specify the equation the way they want you to, not in mathematical format. So, I wrote my own in xf_form.js.

To parse the equation (separate the values from the operators), you need some sort of parsing routine. Those are very complicated to write. So, instead, I make the website programmer place the separate values and operators into an array, in the order of the equation. I figure, they already know and have access to those various parts. So, parsing done! Oh, just make sure the values are numbers and not strings.

Then I wrote a simple routine to evaluate the equation from the array. You can use operators **, *, /, +, -. These are evaluated based on mathematical rules – ** first, then * and / left to right, Then + and – left to right. I was going to provide for % (remainder), but who knew what order you wanted that evaluated in.

I provide input fields for all the values and operators. The operator fields are readonly, though you could not make them readonly and let the user enter their own equation. Because the keyboard operators threw off my vertical alignment, I display other similar symbols, but the value is still the keyboard operator.

But, your equation still might have nested equations: 1+2*(3+4). 3+4 is nested. Innermost equations are evaluated first. I used data-calceq to specify the level. For 3, +, 4, data-calceq=”2″. For 1, +, 2, *, data-calceq=”1″. Now I need somewhere to store the result of 3+4. I call this hidden input field xf_calc_resultN where N is the level number – in this case 2. xf_calc_result2 has data-calceq=”1″.

Now I call my routine to evaluate the form, passing the form id. Form has data-calceqs=”2″ (the number of equations). My routine gets all the children (descendants) of the form. It evaluates the equation where data-calceq=”2″. Then it evaluates the equation where data-calceq=”1″. If you had 10 equations, it would evaluate them from 10 to 1.

The result of equation 1 needs to go somewhere. I place it in an output field with id=xf_calc_result1.

onsubmit=my form evaluation routine, evaulates the form when the user clicks the submit button, which I’ve titled Calculate. Everything’s fine, all javascript, all simple, all client-side. However, there’s one wee problem. As soon as the user clicks the submit button, the equation is evaluated and displayed, then the form is cleared. To keep the form from clearing, add another function to onsubmit. onsubmit=”xf_calc(form_id);event.preventDefault()”. The Default that is being prevented is clearing the form. That’s not technically correct, but that’s what appears to be happening. What is technically happening is not really important. What’s important is that your form isn’t being cleared and the user can see the results.

If your formula’s not too complicated, you can use xf_calc. Otherwise, you’ll need to call xf_math_eval(equation_array) multiple times and piece together the results. You can still use hidden input fields for intermediate results.

Stay tuned. Next time, I’ll finish up with a menu form. Then I’ll tell you where you can find out more about xf_form.js.

Expressive Forms – Part 2

Programmer

Part 1 was an introduction to Expressive Forms. In Part 2, I’ll cover a contact form because a) that’s probably the one you’re most interested in, and b) it covers the most ground.

With a contact form, you want to collect at least an email address and receive that email address in an email to yourself. You probably also want to collect the potential client’s name. Perhaps their phone number. And, some info about why they’re contacting you.

Most email forms reach out and grab you. I hate when that happens, so I don’t advise doing that. Rather, make the form obvious (or the click of “Contact Me”). Let the user reach out. After all, I want clients who want to engage with me, rather than those who happen to be swept to my shore and almost drowned in the process.

So, go ahead and design your form. On my test contact form, I had Reason for Contacting Me. This is typically a list of choices including “Other”. If you want a list, use a <select> element, otherwise, use an <input type=”text”> element. With <select>, you place each option in <option> tags. And you can group <option>s in <optgroup>.

Next, I want their name – <input type=”text”>. For each field where the user will enter something (or select something), I use a <label>. <label> is related to <input>. <label for=”name”>Enter a Name</label><input id=”name”>. Note that the for of label is the same as the id of input. Also note that there is no </input>.

Next, for their email address. <input type=”email”>. When the user clicks the submit button, this field will be validated as an email address. The validation isn’t very robust. a@b is considered valid. You can greatly improve this validation by adding a pattern. Patterns can get long and complicated, so I won’t go into that here. The great thing is that you only have to supply the pattern. You don’t have to supply any real code to see if the email address matches the pattern.

For my test contact form, I grouped the client’s email address field and a check-box, using fieldset. The checkbox is for whether the client wants to be cc’d on the email. If they are cc’d, they will end up getting your email address. And, at this point, I think that’s a good thing. That way, they can contact me and I don’t have to bug them about it. Still, until that email goes out, my email address can remain hidden. With fieldset, I can include a legend (title for the group/set). No need in this case. Fieldset defaults to have padding which through off the alignment of my fields. I provide a class for that in xf_form.css.

A telephone number, if you wish. <input type=”tel”>. You can just as well say <input type=”text”>, since tel provides no validation. Again, you can use pattern to add validation. However, consider the reason that there is no validation. That’s because international telephone numbers can have a very wide variety of formats. If you want to limit to northern-hemisphere numbers, you can use a pattern for that. But, even UK numbers have a variety of valid formats. If you really want to make sure, the user enters a valid phone number you can use Twilio. However, if it’s me, I’m not going to give you my phone number until we’ve had some initial email conversation. So, why make me mad? You can somewhat validate the phone number with minlength=”6″. You can add a pattern to limit non-numeric input to #,(,), -, and space.

And, what is the real reason they want to contact me. For this, I used <textbox> and allowed them to enter some more text. You might want to add maxlength=”1000″ or possibly less.

Now, there’s one last field that needs to be on your form, and that’s your email address. However, if you wanted the user to be able to see your email address, you would have just supplied them with an email link. Well, it’s not so much the user, whom you don’t want to see your email address, but all those bots lurking about. The best thing you can do for that is to use an excellent webhost for your website. I’ve used Dreamhost for years – so far, so good.

Let’s continue to hide your email address – <input type=”hidden”>. Hidden fields can’t have labels. I tried checking for one and my javascript code just quit. Turns out I first needed to check and see whether my field could have a label before I checked to see if it did. So, I hid the email address. A bot can still easily see it. So, I encrypted it. I used a replacement technique to obfuscate it. I could have really encrypted it but, it’s not a password. It’s only an email address. I made the encryption easy to apply, but hard for a bot to notice and harder for it to reverse. I added that routine to xf_form.js. The routine encrypts and decrypts and allows you some control over the encryption.

I used the data-process attribute to tell this field what routine to call to decrypt the email address. data-… is an attribute that you can specify. The attribute starts with data-, and the rest is whatever you want. So data-process. You can easily retrieve whatever’s in data-… with element.dataset…. Typically, you might have data-email-part=”to” to tell you that this field goes into the to of the email. However, javascript sees that as dataset.emailPart. Since I think that emailPart is confusing – which letter should I make uppercase? – I used data-emailpart. Then I know that javascript uses dataset.emailpart.

Every field on my contact form gets a data-emailpart to tell it if this information goes into the To, CC, Subject, or Body of the email. You have to encode the spaces, and I use decodeURIContent for that.

xf_form.js provides xf_send_email(form_element) to send the email when I click the submit button. The flow of what happens is: The user enters the information into the form. They click Send Email which is a submit button. The form has no action or method. It does have onsubmit=”xf_send_email(form_element)”. First, the onsubmit action validates the form according to minlength, required, pattern, type, etc. attributes. Then it executes xf_send_email. xf_send_email goes through each element and places the information in the appropriate part of an email, encoding as needed. Then it mimics the user clicking on an email link. The user is presented with an email to send.

The drawback to this method is that the user has to click send email twice. That’s ok, you can label the first one create email. They’ll have a chance to grab my email address (though no need as they could have checked to cc them the email. And they can clean up the email, if needed. This also means they can remove information that you wanted to be required.

The good part is, no coding and their information isn’t sent over the web. Well, it isn’t sent over the web outside of the email. If you need something more, use smtp.js to keep your email address secure. In my opinion, what I’ve done is sufficient. And I didn’t have to resort to php and/or server-side code. You don’t even need to write any javascript, other than a little test script to call my routine to encode your email address in the first place.

Just create your form. Add some data- attributes. Add onsubmit=…. And, you’re done.

Stay tuned. In the next part, I’ll explain how to use xf_form.js to add a calculator form to your website. You can combine it with the contact form if you like. And, before I finish this series, I’ll tell you where you can get xf_form.js. It’s free. You don’t even have to fill out a contact form. I’m just waiting until I have the appropriate place to put that information.

Expressive Forms – Part 1

I recently created xf_form.js – a javascript library to help website programmers and designers use simple forms to make their website more expressive. Website programmers have a love/hate relationship with forms. They hate entering information into them, but they love collecting information with them. At least the website owners love the information that is collected with them. But forms can be oh, so much more than an information gathering mechanism. Mechanism, that sounds so dull, doesn’t it.

The first thing you want to do with a form is design it. Most forms have dull and boring designs. Give it some color. Place a background in the form. Make the fields transparent and show your logo through them. Just a little css for styling, and you’ve made it more expressive.

So, why xf_form.js? Well, you need a script/scripts to process the information. In the old days, you’d design a form using HTML and CSS,. The form would send the information to the back end (server-side) where it would be processed and sent to you. That’s still the way many forms are processed. The back-end code is tedious, not pretty, and specific to the form (or form type). It’s back-end so that it’s harder to hack. But why not make it simpler. In fact, why not bring it to the front end (client-side). Unless we’re talking passwords, we can still make it hard to hack. I can show you how to keep the client’s information safe. And besides, we can do more than just collect information with a form. We can use a form to process information.

I created three sample forms using xf_form.js. Well, I created them with HTML and CSS. But their data is processed with xf_form.js. The first form is a contact form. Don’t worry, I’ll explain how to have the client send you an email using a form without exposing their information to the internet. It’s simpler than you think. The second form is a calculator. Perhaps I’ll replace my form calculator which shows you how much money you can save with an Electric Car, with xf_form.js. The third is a menu. The menu could be a div, rather than a form and still use xf_form.js. I’ll be featuring this type of menu in my upcoming bookstore website. My javascript routines expand and collapse the menu.

To be continued … Check back for How to Process a Contact Form.

Coloring Google Charts

Programmer

I recently updated my xg_graph.js javascript library to allow coloring of Google graphs. (Google calls them charts). xg_graph.js makes drawing bar, column, line, pie, table, and geo charts easier. Line charts can contain lines or points or both. Pie charts can have a hole in the middle, in which case they’re a donut chart.

So, what can you add color to on a Google graph? Google graphs have colors by default, so you’re not adding colors, you’re overriding colors. This is even true, when you’re giving the text a color other than black.

For a bar chart, you can override the colors of annotations, the background, the background of the chart area, the colors of the bars, items along each axis, items in the legend, the title text, the tooltip or hint (the text that appears when you hover over something), and trendlines. You can maybe override background color, text color, border color, and/or transparency, depending on what you’re overriding the color of. Note: To override transparency, you override opacity which is the opposite of transparency. When will css add transparency to styling? That’s what I’d like to know.

While you can override colors for all those various things on a bar chart, xg_graph.js only allows you to override the primary coloring, which is for the bars. Bar, Column, and Line charts come in two basic fashions. In the first one, there are single bars/lines. In the second, there are multiple. When there are multiple, these are called series. The first of the series is called the primary. In the case of bar and column charts the series can be stacked on top of the primary.

So, the question comes, if you’re coloring the bars are you just coloring the primary bars, are you coloring the series, or both? Let’s talk about the series first, because that’s easier to color. You can color the series with the colors option. Just provide an array of colors. There is also a series option which accomplishes the same thing. However, you have to provide an array of objects, whatever those are. I use the colors options.

Google graphs use 31 default colors for the series. If you have more than 31 series (and why would you), the colors start repeating. In 2014, Google start providing Material charts. Material charts use Google’s Material Design Colors. When coloring series for Material charts, the first three series are different shades of blue, then next three are different shades of red, then orange, then green, purple, aqua, peach, gold, blue violet, pink, and now we’re up to 30. Even though it’s been 8 years, Material charts are in beta.

To color each primary bar differently, you have to add a style column to the data array. In your data array for Google graphs, the first row is headings. The heading for the style row is {role:’style’}. The brackets indicate that this is an object. This column for the other rows can contain the color ‘red’, or an object which is the style {color:’red’,opacity:50%}.

If you’re confused at this point, don’t worry, I’ve made it easy. To draw a graph with xg_graph, you place some code in the <head> of your webpage. Then you call xg_graph_google_init(‘bar’) or whatever graph type you’re drawing. This sets xg_graph_color_scheme to ‘default’, which will make it use the default colors. Then you set up your data array. To change the primary bar colors, change xg_graph_color_scheme to ‘primary’. Define a color array, and call data_array = xg_graph_google_apply_color(data_array, color_array). If you don’t specify enough colors, the colors you specify will be repeated. This adds that style column to your data array for you. To change the series, set xg_graph_color_scheme to ‘series’ or to ‘primary+series’. Then call xg_graph_google_apply_color(data_array, color_array). The data array doesn’t need to be updated, so don’t say data_array = …. Series colors are kept in a global array behind the scenes.

Let’s talk about pie, pie graphs to be specific. Donut graphs aren’t separate from Pie graphs for Google. You just specify the size of the pie hole. If there’s a hole, it’s a donut graph. It’s too bad that you can’t make the hole transparent and place an image of ice cream below the pie graph. Then you’d have a pie a la mode graph. Well, maybe you can, try setting background color to ‘transparent’. If you get this to work, let me know.

Another thing to note: Pie graphs can be 3D. Donut Graphs cannot be 3D. Pie graphs are the only type of Google graphs which can be 3D. You can somewhat fake 3D for Bar and Column graphs, by specifying border colors in the style column. I provided for 3D Pie graphs. I didn’t provide for fake 3D Bar graphs.

For pie graphs, xg_graph_google_apply_color colors the slices. This could have been done with either the colors or slices option. I used colors, because slices is an object, so more difficult. These colors work the same way as series. But, since there is only one option, you don’t have to change xg_graph_color_scheme. It is changed for you.

Geo graphs are maps made of line drawings. Google also has map graphs which use google maps and markers. Markers and colored text on geo/map drawings require you to obtain a maps API key and let Google Graphs know what that is. I didn’t provide for that.

By default, Geo graphs color the regions/locales in your data_array with a white-green gradient. A gradient varies the color based on the gradient colors. So the countries with lower values will be more white. Those which higher values will be more green. Geo graphs are always going to color locations based on a gradient.

For Geo graphs, it looks like you’re stuck with a gradient. However, you can give that gradient whatever colors you want, and as many colors as you want. Call xg_graph_google_apply_color(data_array,color_array). For the previous graph types, colors in color_array are repeated until there are enough colors. For Geo graphs, they’re not. If your color_array contains red, orange, yellow, green, blue, and violet, the countries will be colored using a gradient made of all those colors.

But wait, what’s this? If your data_array contains n locations and your color array contains n colors, each location is colored differently. If you want to color each location with a separate color, xg_graph.js also allows you to do that with an svg (a specific image type) map. You have to provide the svg.

And last, but not least, table graphs. A table graphs displays data in a table. The user can sort the data. You’ve probably seen these somewhere on the internet. Perhaps in Wikipedia. In a table graph, you may want to sort the various rows. By default, Google uses a white lavender gradient for the header row. Then, every other data row has a background of snow. With xg_graph.js you can apply background coloring to the header row. You can also apply coloring to either all data rows or to every other data rows. Table rows are styled using the cssColorNames options. This is an object containing the class names to be used in styling the rows.

In xg_graph.js, you need to provide the following classes, if you want to color the rows: xg_table_header_color, xg_table_row_color, and xg_table_alternating_row_color. Each class should contain background-color. The header row background color will be a gradient of white and whatever color you specify. If xg_graph_table_alternating_row_style=true, every other row background is colored. Since these classes are styles, and since you’re providing the classes, you can specify more than just background-color. Since coloring a table graph is based on classes, rather than the data array and color array, call xg_graph_google_apply_color(”,”) to apply coloring.

That’s it. If you want to provide other coloring or if you want to color other types of google graphs, you’ll need to code that yourself, unless you talk me into providing that capability in xg_graph.js. I provide the simpler coloring. The rest looks like it gets more complex.

Helper Routines for Google Graphs

Programmer

Google calls them charts, rather than graphs.

I updated my xg_graphs.js javascript graphing library. Before, I had provided for easy svg manipulation. This time, I wanted to add simple bar (horizontal) and column (vertical) graphs. I realized that the graphs wouldn’t look that good. And I won’t mention that it was getting way too complicated. So, I started looking for alternatives. I ended up writing helper routines to make using Google Graphs more simple.

I hesitated to use Google Graphs, because I like to keep my footprint small – makes for faster loading and uses less energy. Yet, I knew that Google would keep things as light as they could. So, I went down that route and I like the results.

Using Google Graphs, you can create all sorts of graphs: annotation, area, bar, bubble, calendar, candlestick, column, combo, diff, donut, gantt, geo, gauge, histograms, interval, line, map (uses satellite images rather than line drawings as geo does), org, pie, sankey diagram, scatter, stepped area, table, timelines, tree map, trendlines, waterfall, and word trees. I only coded for the most popular types of graphs. I’ve never heard of some of these graph types.

Donut charts are Pie charts with a pie hole in the middle. Bar and Column charts are similar, the bars just go different ways – horizontal vs vertical. A Table is a sortable table as you may have seen somewhere on the web. Geo charts use maps to graph things – slightly similar to my svg graph routines.

You can read the documentation here. I kept it simple and generic, which meant there are limitations. Still, my routines will help you draw a nice looking graph, simply. I’ll be adding more functionality. And I’ll be posting about those improvements.

A Generic Substring Function

Programmer

You may not remember the PL/I programming language (that’s a roman numeral 1, not an uppercase i), but I do. Well, not a lot. What I do remember is that the code looked like the programmer. That is, it looked like the programming language that the programmer knew. While, this is true of all programming languages, PL/I was designed with this in mind.

But, back to substrings. One substring of abcde is bcd. Depending on the language you’re programming in, the substring function or method is written differently. Function is typically, substr(string,start,end). Method is typically string.substr(start,end). The differences are in the name of the function / method and in the start and end.

Let’s take excel for instance. If you’re writing a formula, the substring function is mid (for middle). mid(string,start,length). In this case, start is the starting position. And length is the number of characters to return. mid(“abcde”,2,3) returns “bcd”. If you’re in excel writing macros (vba), it’s the same function, which is nice.

COBOL is similar. SUBSTR(STRING,START,LENGTH). The only difference is the name of the function.

Javascript uses the method substr(string,start,length). The difference here is that start is an index, rather than a position. Javascript is zero-based. VBA, etc. are 1-based. Therefore index is one less than position.

According to Mozilla, substr is deprecated in favor of substring and slice. W3Schools just says, substr is part of Javascript and is supported by all major browsers. ICanUse agrees with W3Schools. And, I’m not finding anything in the javascript (ecmascript) documentation that says it’s deprecated. Perhaps Mozilla is planning to not support this in their Firefox browser. I figure as long as there’s plenty of substr functions out there, they and all the other browsers will support it. So, I continue to use it.

But what about that substring and slice function? Python doesn’t even provide substring, only slice. How are they different?

substring and slice methods use the same format, other than the name. string.slice(start,end). You can get fancy and use negative values for start and end. If you do, substring and slice work differently. I suggest that you not do that, because whoever has to maintain your code, may get confused. In my case, that would be me.

So, instead of specifying the length or number of characters to return, substring and slice specify the end index. However, they make it (IMHO) complicated. Start and end both refer to indexes. However, start is inclusive and end is exclusive, according to Python documentation. What that means is the start index is where the substring starts. The end index is one character after where the substring ends. If you weren’t confused before, you probably are now :(.

All programming languages that I researched (and I researched about 15), use one of those syntaxes to return a substring, though they might call the function / method something different. Lisp calls it subseq and uses the slice syntax.

So, how to make one substring function which allows programmers to use the syntax they’re used to? I think that’s important, because getting the parameters wrong can cause havoc. Trust me on that one.

I added x_substr function to my x_press.js library as an example generic substring function in javascript. First, you have to work in the language that you’re programming in. For javascript, that means start and end have to be converted to indexes, if they’re not passed that way.

You also have to know whether the programmer is passing positions or indexes (or lengths). I determine this with parms. x_substr(string,start,end,start_type,end_type). start_type and end_type are arrays. The first element of the array is pos, ind/idx, or str => Position, Index, or String. Notice that I introduced a new way of returning a substring – identify it with strings. For end_type, the first element can also be len for length. The second element is bef, at/on, aft – for before, at/on, or after. VBA syntax is at or on for start. Slice syntax is at/on for start and aft for end. Perhaps I should add sli for slice. For len, the second element should be ”. In addition to adding str for either start or end, I also added bef. I figure to be fully generic, if there’s an aft, there must be a bef.

substr(string,start,end,[‘pos’,’at’],[‘len’,”])

substr(string,start,end,[‘ind’,’at’],[‘ind’,’aft’])

After I determine what the start and end indices actually are, I have to extract the substring and return it. I used a simple for loop to accomplish this. Using slice may have been slightly faster, but not enough to matter. And besides I understand the for loop, sort of.

SVG Images Made Easy

Programmer

Well, at least made easier. IMHO, svgs are not easy to understand. svg is a type of image for websites. svg stands for scalable vector graphics, whatever that means.

The important part is that you can manipulate these images in real time. This can also be difficult – it was for me for a long time. It’s possible to alter other types of images in real time. However, svg is what most people use. Canvas is an alternative to svg. But in my opinion, it’s not any easier to understand.

The simplest way to put an svg image on your website is to reference it with the img html tag. But that doesn’t allow you to manipulate it. If instead, you copy the svg image into your html page and make it inline svg, you can manipulate it. Keep reading and I’ll explain how that can be done fairly easily.


An svg image is a text file of commands to draw the image. You can open it with a text editor like Notepad++. This file looks similar to html. It starts with <svg> and ends with </svg>. Actually there may be some code before <svg>. To place your svg image inline, decide where you want it in your html and pasted everything from <svg> to </svg>. Do not include anything before <svg> (or after </svg>). It is not needed or even wanted in some cases in the inline version.

Now that you’ve pasted in those several lines of svg code, save your html file and open it in a browser. Voila, there’s your svg image on the screen. Hint: I find that it helps me immensely if I put comments around the svg. I put <!--SVG--> before the svg and <!--End SVG--> after it.

Now, to the fun part – manipulating the image.


I wanted to take a map of the USA and color each state based on certain criteria. OK, so I wanted to color each state depending on who won during a presidential election. I did this a couple of election cycles ago. It was hard work. Each time, I changed the svg file manually, then I opened it in my picture editor. I made a screen copy and saved that as a png image. Then I referenced that on an img tag in my html page.

Recently, I thought that perhaps I might want to be able to do the same sort of thing at some point in the future. So, I wrote some javascript to simplify that process. I’ve placed that javascript in xg_graph.js and uploaded it to the internet. I tried to make it as simple as possible, so that you don’t need to know much about coding.

You can read about the details of how to use that code at Really Useful Javascript Graphs. I’ll discuss the basics here.

I used the USA svg map from Wikimedia. The particular svg map I used is free to use, no attribution needed. Some svgs are free to use, but require three attributions, plus a brand logo. I think three attributions is asking a little much. But then again, I don’t need that particular svg image yet. Others svg are not free.

You can create your own svg, maybe, using Inkscape or Adobe Illustrator or maybe something else. I can’t draw, so that’s out. And probably the svg will be easier to manipulate if you use one that somebody else has created and gone to the trouble of identifying separate parts of the image.


An svg file consists of the svg or multiple nested svg. Within an svg, you can have a group (g) tag. This groups elements together. If you don’t have <g>…</g> tags, you will probably want to add them, at least one set. Just place <g> at the top at the end of <svg…> and </g> at the bottom before </svg> if you don’t know where to put them. Some of my javascript routines rely on the group tag. There are also shape tags – path, circle, eclipse, line, polyline, polygon, and rect (for rectangle). And that’s pretty much all you need to worry about: svg tag, group tag, and shape tags.


<path class="co" …><title>Colorado</title></path> is the shape for Colorado (CO). It’s identified by both the title and the class. Luckily, the shapes were identified, so that I didn’t have to figure that out.

However, my routines rely on tags being identified by ids. The Wikimedia file doesn’t have ids. But that’s easily resolved. I just add ids to the svg, group, and paths. In this case, I modified the Colorado path to be <path id="svg_co" class="co" …><title>Colorado</title></path>.

Now that my tags have id’s, I can call my xg_svg_modify routine to modify any attribute – class, bgcolor (background color), transparency, title, or text. Text can get complicated, so I manipulate title instead.

You can also modify the size of the svg. And that’s mainly what I use this routine for. It’s more complicated to change the size of an svg than just altering the width and height attributes. It took me a day or two to understand what people on the web were trying to tell me. And even then, I didn’t want to do it manually. So, a routine.


Back to politics. When I find out who won, I can call my x_who_won routine to assign the correct background color to a state shape. Yes, that’s easy enough to do manually when only two people are in the race. But what about a presidential primary when there are 16? And what about election night at 2am, when you’re waiting for the results to come in and you’re way too tired to think straight. When you find out the correct color, you can call xg_svg_modify to update it.


That’s great! But, I want to work with the svg as a whole, rather than one shape at a time. First I need to know the attributes of each shape. So, I call xg_svg_group_init. This gathers the attributes of all shapes in a group. It gathers those attributes into arrays. Arrays can be difficult to work with in javascript. But they were necessary in this case. And, I tried to keep them simple.

You will need to know the index of the array for a certain shape in order to update its attributes: co_index=xg_svg_shape_id_array.indexOf('svg_co'). This returns the index for the Colorado shape in the array. co_bgcolor=xg_svg_shape_bgcolor_array[co_index] returns the background color for Colorado. To update the background color to blue, xg_svg_shape_bgcolor_array_update[co_index]='blue'. You may also want to update the titles by appending the scores. xg_svg_shape_title_array_update[co_index]='CO 55 45'. Then call xg_svg_shapes_update to update the svg.


Maybe you’re not interested in politics. Maybe you just want to randomly color each state. My routine x_color_random_array_init creates the array x_color_random_array. After calling x_color_random_array_init, call xg_svg_shapes_update_bgcolors(x_color_random_array). Then call xg_svg_shapes_update to update the svg.

Website Color – Contrast, Primary, Random

artists pallette

Contrast

If the background of an element is dark, you want a light (typically white) text. If it’s light, you want a dark (typically black) text. But what’s dark and what’s light? Technically speaking, light colors are those whose red, green, and blue components are greater then hex 7f (decimal 127). However, our eyes are tricky creatures, and that doesn’t always work. Instead, you need to know the lightness component. You can convert the color to hsl (hue, saturation, light), but that’s rather involved. There’s also a one line if statement I found somewhere on the web which will do the trick instead.

if(((red_component*299)+(green_component*587)+(blue_component*114))/1000>128){contrast=’black’}else{contrast=’white’}

Of course, first you have to get or know the background color of the element. Then you have to convert it from whatever color system it was specified in to rgb. The color system could have been hex, rgb, or an official color name. It could have been a few other color systems. If it is, you’ll need to deal with that. Otherwise, see my functions below to help with this.

Primary Colors

What are the primary colors? Google this and you’ll typically get primary, secondary, and tertiary color names. Some people think of primary colors as the colors of a rainbow. Others think of it as the colors in an 8-crayon box.

My list of primary colors start with those where the hex red, green, and blue values are 00 or FF. This gives us Black, Red, Yellow, Green, Aqua/Cyan, Blue, Magenta/Fuschia, and White. Then I add in those colors where one or more of the values are 7F, for a total of 15 colors.

Random Colors

A Random Color is easy enough to calculate. Some people take a random value for Red (between 0 and 255), one for green, and one for blue. I just take a random number somewhere between the 0 and the maximum number of possible colors.

In Javascript, this is ‘#’+Math.floor(Math.random()*16777215).toString(16).padStart(6,’0’); I may have missed one color at the top-most value, don’t know, don’t really care. toString converts to hex, padStart adds leading zeros, if any are missing.

The real trick, is how to you generate an array of random colors, without any duplicates? What does duplicate mean? I can’t tell the difference between my wife’s navy blue socks and her black ones. I mean they should be labeled. She can. So, duplicate is a matter of how close to another color is too close? I suppose hsl would work better for this. However, I just define it as the red, green, and blue each being within 16 of the red, green, blue of another color. If that doesn’t work for you, you can call my routine passing a different value for tooclose. You’ll probably want to pass a value > 16, like 32.

I also allow you to not accept grey, black, or white values in your array. The array can contain 1000 values. However, if you disallow grey, black, or white, it may contain slightly less than 1000 values. It may also contain slightly less than 1000 values due to dups. I figured 900+ values should be sufficient for most applications.

x_press javascript functions

If you need to add some basic javascript functions to your website to deal with colors, check out my free javascript library. It’s designed to make your website more expressive. And it’s easy to use, even if you don’t know much about javascript.

 

x=x_color(elementID,foreback) will return the foreground or background color of the element. Foreback can be ‘text’,’foreground’, ‘fore’, ‘fg’ for foreground. Foreback can be ‘background’,’back’, ‘bg’ for background. Any other value will return the background color.
x=x_color_shift(rgb,redshift,greenshift,blueshift) will shift the color. Use positive value for shift for lighter, negative for darker. Specifying 16 or -16 will go slightly lighter or darker.
x_color_primary_array contains primary, secondary, and tertiary colors.x_color_primary_names_array contains the names. x_color_primary_n_array and … names array contain primary colors in sorted order where number of colors is n and n=5,8,15. Brown is actually a red-violet shade, so not included.
x_color_blackx_color_white – black and white, but you can change them to whatever you use for black and white. I was going to set x_color_text and x_color_background to document.body.style.text and document.body.style.backgroundColor, but these would be set in x_press_init. And x_press_init is usually called in <head>. And document.body.style…. is in head. You would need to set your own variables for these in a script after <body>. You might also want to set a variable for document.body.style.borderColor. You can of course you document.body.style…. The only reason for corresponding variables, would be if you can’t recall document.body.style….
x=x_color_convert(fromcolor,tocolor_type) will convert color from one type to another. From type is name, hex, or rgb and is derived from fromcolor. tocolor_type needs to be specified if rgb, otherwise it defaults to hex. tocolor is the returned value.
x=x_color_random_array_init(allowgray,allowblack,allowwhite,tooclose) loads an array of up to 1000 random colors. By default, gray, black, and white are not allowed. The array may contain slightly less than 1000 colors, especially if you disallow gray, black, and white. Also, duplicate colors are not included in the array. Duplicate in this case means that the color is too close to another color in the array. tooclose defaults to 16, meaning the red, green, and blue values are within 16 of each other. You can change tooclose. I suggest increasing it, like to 32. Increasing tooclose raises the chance that the array will contain less than 1000 elements, but you’ll probably still have plenty.
x=x_color_contrast(color) returns a contrasting color. Typically, you have a background color and you want to contrast the (foreground / text) color.
x=x_color_contrast_per_background(x_el,settextcolor=false,setbordercolor=false) returns a contrasting color based on an element’s background. Optionally sets text and/or border colors. This works for elements. It does not work for document.body. To set, document.body.style.color=x_color_contrast(document.body.style.backgroundColor)

Add Animated Cards to your Website

Programmer

I should have added the word Easily to the title of those post. Alas, I didn’t.

When writing my fantasy series, The Wizard without a Wand, I had trouble keeping track of all the characters. First, there’s the tensome – ten Wizard School students who hang out together. They even share the same dorm room – the school calls their dorms hotels. Even so, we all know they’re just dorms, not hotels. Then there are parents, teachers, the Principal, etc.

I figured, if I had trouble keeping them straight, my readers might also. So I added a cast of characters at the end of each of the ten books in that series. I didn’t intend for there to be 10 books. I didn’t even intend for it to be a series. That just happened.

Anyway, when I added that series to my website, I decided to add the cast of characters to the website also. Then I decided to get fancy, and put each of the Tensome on a card on the website. I wanted the card to be animated, so that when a user clicked it, it would turn over and show the user more information.

In order to have the card turn over, I animated it. I created my own animation routines in javascript. These are free and easy to use, provided you can understand javascript just a little bit. And provided you can add javascript to your website. I call this library of routines xa_animate. It goes along with my x_press javascript library which helps make your website more expressive. These libraries are accessible at https://stubbart.com/computer_consulting/code/index.html

You can use these animated cards for playing cards, greeting cards, or business cards. You might want to use a card for each of the top people in your company on your company’s website.

Turning over the card, means rotating it. For my children’s superhero series Zuper Zero (Only three books this time, so far. Again, series was unintended.), I wanted the front of the card to slide into the sky. So, I added the Scroll method to the Rotate Method.

Then I added the Slide method (a variant of the scroll method with more options), the Fade method, and the Open Method.

In my scifi book Shalomar (no series this time), one of the main characters is named Glo-Reta. One of my favorite lines from that books is, Life wasn’t bad, living with Glo-Reta in Gariza. Anyway, I wanted the front of the card to glow as it disappeared and showed the back. So, I added the Filter method.

The Filter method is a repeat of the Fade method, however, in addition to opacity (opposite of transparency), you can apply blur, brightness, contrast, grayscale, hue-rotate, saturation, and sepia. My test picture glowed the best with brightness and contrast. Glo-Reta’s glowed the best with brightness, grayscale, and hue-rotate. I have no idea why grayscale helped. hue-rotate alters the color, so yellows become purples, or some such.

https://stubbart.com/computer_consulting/code/xa_animate.html – xa_animation documentation and examples.

https://stubbart.com/publishing_consulting/cast/wizardwithoutawand.html – Wizard without a Wand – Cast of Characters

https://stubbart.com/publishing_consulting/cast/zuperzero.html – Zuper Zero – Cast of Characters

https://stubbart.com/publishing_consulting/cast/shalomar.html – Shalomar Cast of Characters