Really Useful Javascript Graphics


by Dale Stubbart

Expressive Graphics for Websites

To make certain that you&';re up-to-date with the latest changes to my Expressive Websites Javscript Library, and I will send you updates when I make changes.

Changes
Version 7.1.1 - Added xg_graph_table_sort_column, xg_graph_table_sort_ascending. You can change these values, but the table will take longer to display. Also fixed allowHtml.
Version 7.1.0 - Added xg_shape_style
Version 7.0.0 - Added xg_shape_draw
Version 6.0.0 - Renamed to xg_graphics.js. Renamed xg_graph_init to xg_graphics_init
Version 5.6.0 - Added Gauge Graphs
Version 5.5.2 - xg_graph_color_scheme can be 'specific' for geo graphs
Version 5.5.1 - Improved background process for coloring primary bars/lines
Version 5.5.0 - Added line graphs
Version 5.4.0 - Added coloring to tables - required css classes. Geo charts can only be colored based on gradient.
Version 5.3.0 - Added colors option to tables (doesn&';t do anything), and geo charts - adds colors to gradient
Version 5.2.1 - Table charts - added allowHTML and alternatingRowStyle options
Version 5.2.0 - Bar and Column charts can be colored.
Version 5.1.0 - Pie charts can be colored.
Version 5.0.1 - Allowed hole for pie chart. Pie chart defaults to 3d; but 3d can't be true if there's a hole. So, if pie chart with hole, 3d is false. This was already working for donut chart which is a pie chart with a hole.
Version 5.0.0 - Fixed maximum stack error; straightened out flow; removed xg_google_graph_update - updates are done in draw, not needed; minimized footprint; etc.
Version 4.2.0 - Allowed multiple graphs on same page
Version 4.1.0 - Renamed google drawing routine from xg_graph_google() to xg_graph_google_draw()
Version 4.0.1 - Moved load for google graphs from xg_graph_google_init() to xg_graph_google()
Version 4.0.0 - Separated xg_graph_init() into xg_graph_init() and xg_graph_google_init(graph_type). xg_graph_init() has no parms.
Version 3.3.1 - Added safeguard against loading google routines multiple times. Probably won&';t happen, but just in case.
Version 3.3.0 - Added geographic charts
Version 3.2.0 - Added table charts
Version 3.1.0 - Added bar charts
Version 3.0.0 - Realized that my attempts to create a bar graph would not produce a very nice looking bar graph. And, it was getting too complicated. I then wrote helper routines for Google Charts to create a pie chart.
Version 2.0.0 - Added xg_graph_init and other functions in an attempt to create simple horizontal and vertical bar graphs.
Version 1.0.0 - Added xg_svg routines.


If you want your website to be more expressive - use svg maps, google graphs, and draw simple shapes - please use my xg_graphics.js javascript library. If you do use xg_graphics.js, etc., attributions are helpful, links are more helpful, posting articles is most helpful, and donations (link at top of page) are always helpful. (Helpful to me and to others who could benefit from this library. Donations offset my webhosting and usage costs which go up when more people use my code.)
xg_graphics.js contains several functions which are explained below. You have two options for using xg_graphics.js. You can download files to your desktop and upload them to your website, or you can link directly to my code.
Downloading ... Your code is static until you download again. If I change the code, it doesn&';t affect you.
Click on the files below to download them. Then, upload them to your website. Finally, place <script src="yourpath/xg_graphics.js"></script> and <link rel="stylesheet" type="text/css" href="yourpath/xg_graphics.css" /> in the <head> of your html. yourpath is where you upload these to on your website.
If you just want to point to my code without downloading and uploading, place https://stubbart.com/computer_consulting/code/ in place of yourpath/ above.
Whether you download or point directly to my code, please so that I can inform you of updates.

Files to Download:
Graphics function library
Graphics function styles

If you&';re using Google Graphs, point to the Chart Loader. <script src="https://www.gstatic.com/charts/loader.js"></script> - this is Google&';s Graph routine loader. It is needed for xg_google_graph routines. xg_graphics.js is used in conjunction with my x_press.js javascript library. That library contains several functions to make your website more expressive. See that x_press documentation here. These libraries are quite small and will load fast.

xg_svg routines apply coloring and titles to svgs, usually to svg maps. This is one method of drawing a graph.
For other types of graphs, please see my Google Graph Helper Routines. xg_shape routines draw shapes.
xg_graphics.css can be included for any xg routine. However, xg_graphics_css only contains classes for xg_shape routines. So, it is only required for those routines, and only when one of those classes is used.

xg_svg routines

xg_svg routines are xg_graphics_init, xg_svg_modify, xg_svg_group_init, xg_svg_shapes_update.
You don&';t need to know much about svg to use my svg routines. Svg (scalable vector graphics) is an xml-like language for creating graphics. xml is similar to html in style. What this means is that there are tags. The main tags are <svg>, <g>, and <path>. Several websites sell svg maps. Sometimes you can get one for free, provided you give an attribution. One of those sites requires three attribution links, plus a logo link. The US map on this page is available for free on Wikimedia. This particular map doesn&';t require attribution. And it can be used commercially. Be sure to check the License for whatever svg map you use.
The svg map is a file with the .svg extension. Right-click and open it with a text editor like Notepad++ to see the contents. There are multiple ways to place an svg on your website. It can be the src attribute of an img tag. You can paste it into your html page. It can be referenced by an object, embed, or iframe tag. If it&';s part of an img tag, you can&';t manipulate it. You can do that with the other methods. It will draw the fastest if you paste it into your html code. The one website I found which talked about all 5 methods, said not to use the last two, and to only use the object tag when necessary. So, I only wrote my svg routines for inline (pasted into html) svgs. When you paste your svg into your HTML, remove the xml tag at the beginning.
The svg on this page is 58kb. There&';s a lot of information on the web about condensing your svg. The best site I found for making this svg smaller was svgedit. svgomg came in second. Both made it illegible. In the end, I figured out that the websites which were talking about condensing svgs, were talking about svgs which were MB in size, not KB. So, I left this one as is. The biggest factor in reducing the size of an svg, seems to be that some svgs contain numbers which have 6 digits to the right of the decimal point. And there are lots of numbers in an svg (usually coordinates). 1 digit to the right is sufficient.

Here&';s what you need to know about svg to use my routines. svg is enclosed in an svg tag. There can be groups. This is the g tag. And there are path tags. Those are the main tags. Each of these tags can have a title and/or text tag.
svg tag is the entire svg, though it is possible to have an svg within an svg. g tag groups paths together. path tag is a drawing. In the case of this svg, path is a &n-; state.
My svg routines allows you to use an svg for a graph. What this means is you can change basic things like the background color, transparency, and title of paths within a group. If you want to change other things, change the coding of the svg. The easiest way for code to change the background color, etc. of a path is to know its id. This svg didn&';t come with ids. That&';s ok, you can change it. You want the ids in your svg to not be the same as other ids in your html.


xg_svg_modify(id,[[attribute,value],...]) modifies an svg element. Typically, it modifies the svg, an svg group (g), or an svg path. Just pass the element id, the attribute, and the new value.
You can modify the class. In this case attribute is 'class', value is the new class.
You can modify the background color. attribute is 'color' or 'fill'. value is a color value in hex, rgb, etc. formats – just like in CSS.
You can modify the transparency. attribute is 'transparency', 'opacity', or 'fill-opacity'. value is the transparency or opacity percent.
You can modify the title. attribute is 'title'. value is the title.
You can modify the size. That is, you can modify the size of the svg when it displays on the screen. attribute is 'size'. value is the screen width of the svg.

This svg specified the width and height. However, that width and height are the width and height relative to the coordinates of the svg. They are not the width and height relative to the screen.
To modify the viewable width manually, you would need to add the viewBox attribute. viewBox="top left width height". Copy the width and height to the viewBox width and height. Make the viewBox top and left = 0. Replace the width with the new width. Calculate the height to be new width / original width * original height.
Use my routine. It&';s much easier.


xg_svg_group_init(group) returns arrays which contain information from an svg group.
An svg object can contain groups. This routine is useful for collecting information about shapes in a group and about the group itself.
If your svg doesn&';t have groups, and you just want to collect that information about all shapes in the svg, you have two options. You can try to use this routine, passing the svg id, rather than the group id. Or you can add a group manually. Don&';t forget to assign an id.

The information is collected in arrays. xg_svg_group_array holds information for the group. xg_svg_shape_xxx_array holds information for the shapes which are children of that group.
xxx=id contains the id.
xxx=tagname contains the tag – g for group, or the shape - path, circle, ellipse, line, polyline, polygon, or rect. These shapes are contained in the global array xg_svg_shapes.
xxx=classlist contains the list of classes. If there&';s more than one class, this is an array.
xxx=bgcolor contains the background color. If the background color is specified by a style or class, it is returned as an rgb color otherwise it is returned as specified.
xxx=transparency contains the transparency. If you prefer working with opacity, subtract the opacity from 1.
xxx=title contains the title.
xxx=text contains the text.

Technically speaking, title and text are children of the group or the shape. But I&';m treating them as though they’re attributes. I think that keeps things simpler.

Now that you&';ve collected all of the information for this group, it&';s ready for you to change it. If you want to update the group information, you can do that by calling xg_svg_modify. To change the shape information, you&';ll call xg_svg_shapes_update.


xg_svg_shapes_update(group,attr_array) updates attribute values in an svg group.
To update the svg shapes, first make changes to the copy of the shapes array, which is xg_svg_shape_xxx_array_update.
Making a copy is good programming practice. Also, this update routine only updates things which have changed by comparing xg_svg_shape_xxx_array_update to xg_svg_shape_xxx_array.
To do this, just update the attribute values at the appropriate index. And how am I supposed to do that?!

To figure out what the index is, all you need is the id of the shape:
var index_to_update=xg_svg_shape_ids_array.indexOf(id)
indexOf is case-sensitive.
E.g. To update the background color of a certain shape:
xg_svg_shape_bgcolor_array_update[index_to_update]='blue'
Or you can write this as one statement:
xg_svg_shape_bgcolor_array_update[xg_svg_shape_ids_array.indexOf('svg_oh')]='blue'

Next, you need to specify which attributes you want to update, by passing an array of attributes:
['classlist', 'bgcolor', 'transparency', 'title', 'text']
If you&';re just updating background colors, just pass bgcolor.
xg_svg_shapes_update('svg_state',['bgcolor'])

Both the svg and xg_svg_shape_xxx_array are updated. If you want to make more updates, follow the same procedure. xg_svg_shape_xxx_array and xg_svg_shape_xxx_array_update are from the last time xg_svg_group_init or xg_svg_shapes_update was called.


xg_svg_shapes_update_bgcolors(color_array) updates the colors in xg_svg_shape_bgcolor_array from color_array.
Rather than directly specifying the background color for each shape on your svg, you may want to use rules to update the background colors.

You just want to color every shape. The first way you may want to do that is to just assign each shape a different random background color.
First, call x_color_random_array_init(allowgray, allowblack, allowwhite, tooclose). allowgray, allowblack, and allowwhite and tooclose default to 16. x_color_random_array_init generates an array of up to 1000 random colors - x_color_random_array.
Try x_color_random_array_init(48,64,16,24). This will generate an array of about 300 random colors (perhaps less). The lower these numbers are, the more colors you&';ll get in your array. In this instance, I don&';t care so much for gray. I like black, just not for this map. white is ok for this map. I don&';t want colors which are too close to each other.
tooclose of 32, returns only about 175 random colors because I&';ve said that I don&';t want the colors in the array to be too close to each other. allowwhite in this case doesn’t really matter. You could make it 0 and probably still not get anything that&';s close to white. That&';s because it&';s less than tooclose. The same would be true if allowgray or allowblack were < tooclose.
Then call xg_svg_shapes_update_bgcolors(x_color_random_array). This updates xg_shape_bgcolor_array_update. Then call xg_svg_shapes_update('svg_state',['bgcolor']).

The next way you may want to color every shape, is with an static array of colors. Suppose you want to use the primary colors other than gray, black, or white. x_color_primary_18_array contains 18 primary colors. Minus gray, black, and white give us 15. Your svg probably contains more than 15 colors, so you need to extend or repeat the primary color array.
Use this x_press routine x_array_repeat(array_in, len, exclude_indexes_array) to repeat or extend the array to the length specified, excluding the specified indexes. I tend to set len > what I need, just in case. So, if I need about 50, I set it to 100. The entire array is repeated until there are 100 elements or more.
Black is [0], gray is [16], white is [17]. exclude_indexes_array=[0,16,17].

Your code follows:
var color_primary_100_array= x_array_repeat(x_color_primary_18_array, 100, [0,16,17])
xg_svg_shapes_update_bgcolors( color_primary_100_array)
xg_svg_shapes_update('svg_state',['bgcolor'])
.

Let&';s say that your svg is tracking politics or NFL Teams or some such situation where somebody wins. You want to color shapes a certain color depending on who won. Call x_who_won(high_low_wins,score_array, result_array). If high score wins, high_low_wins='high'. Otherwise, it equals 'low'. score_array contains the scores. result_array contains the corresponding color for each person or team.
Then update that particular index in x_svg_shape_bgcolor_array_update. And call xg_svg_shapes_update(group,['bgcolor']).

You might want to update shape colors based on a range. For instance, if the value < 50, color is red. If < 75, color is yellow, else it&';s green. Call x=x_array_find_in_range(value_in, range_array, return_values_array). range_array=[0,50,75] – the starting value of each range. return_values_array=['red', 'yellow', 'green']
Then update that particular index in x_svg_shape_bgcolor_array_update. And call xg_svg_shapes_update(group,['color']).

Note: The only way I&';ve found to color the DC circle is to add the class .dc to the top of the svg: e.g. .dc{fill:#40E0D0}

Map of the United States with Randomized Colors Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois Indiana Iowa Kansas Kentucky Louisiana Maine Maryland Massachusetts Michigan Minnesota Mississippi Missouri Montana Nebraska Nevada New Hampshire New Jersey New Mexico New York North Carolina North Dakota Ohio Oklahoma Oregon Pennsylvania Rhode Island South Carolina South Dakota Tennessee Texas Utah Vermont Virginia West Virginia Wisconsin Wyoming District of Columbia District of Columbia