Awesome
ticklEcharts
Tcl wrapper around Apache ECharts.
Dependencies :
huddle
package from Tcllib
Usage :
package require ticklecharts
set chart [ticklecharts::chart new]
$chart Xaxis -data [list {Mon Tue Wed Thu Fri Sat Sun}]
$chart Yaxis
$chart Add "lineSeries" -data [list {150 230 224 218 135 147 260}]
$chart Render
# Initializes a new 2D Chart Class
set chart [ticklecharts::chart new]
Argument available :
args | Description | Default value |
---|---|---|
-theme | Theme name | custom (possible values: vintage, westeros, wonderland, dark) |
# Adds the X axis with its values.
$chart Xaxis -data [list {Mon Tue Wed Thu Fri Sat Sun}]
# Adds the Y axis.
$chart Yaxis
# Adds data for line series.
$chart Add "lineSeries" -data [list {150 230 224 218 135 147 260}]
[!IMPORTANT]
-data
property should be a list of list[list {...}]
# Export chart to HTML file
$chart Render
Arguments available :
args | Description | Default values |
---|---|---|
-title | HTML title page | "ticklEcharts !!!" |
-width | Container's width | "900px" |
-height | Container's height | "500px" |
-renderer | canvas or svg | "canvas" |
-jschartvar | Variable name chart | chart_[uuid] |
-divid | Name container's ID | id_[uuid] |
-outfile | Full path HTML file | './render.html' |
-jsecharts | Script echarts.js | https://cdn.jsdelivr.net/... |
-jsvar | Variable name option | option_[uuid] |
-script | Extra JS script | 'null' (see Add script section) |
-class | Specify container's CSS | "chart-container" |
-style | Inline style | "width:'-width'; height:'-height'"; |
-template | File or string template | 'file' (template.html) |
# Example properties :
$chart Render -width "1200px" -height "800px" -renderer "svg"
Data series :
-data
(y values only) :
# Example for lineseries
$chart Add "lineSeries" -data [list {150 230 224 218 135 147 260}]
$chart Yaxis
-data
(x, y values) :
# Example for lineseries
$chart Add "lineSeries" -data [list {Mon 150} {Tue 230} {Wed 224} {... ...}]
# Mon = X value
# 150 = Y value
# Please note : X data is not included.
$chart Xaxis
$chart Yaxis
-dataItem
:
# Example for lineseries
# Additional options are valid, see ticklecharts::lineItem in options.tcl
$chart Add "lineSeries" -dataItem {
{name "Mon" value 150}
{name "Tue" value 230}
{name "Wed" value 224}
{name "Thu" value 218}
{name "Fri" value 135}
{name "Sat" value 147}
{name "Sun" value 260}
}
-dataset
:
set data(0) {
{"Day" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"}
{"value" 150 230 224 218 135 147 260}
}
# Init dataset class.
# Note : Starting from version '2.6', it is possible
# to add several 'items' like this :
# > [list [list source $data(0) sourceHeader "True"] [list source $data(1) ...]]]
set obj [ticklecharts::dataset new [list source $data(0) sourceHeader "True"]]
# Add '$obj' to dataset property.
$chart SetOptions -dataset $obj
# Add line series.
$chart Xaxis
$chart Yaxis
$chart Add "lineSeries" -seriesLayoutBy "row"
Useful methods :
- Get default options according to a
key
(name of procedure) :
# e.g for series :
$chart getOptions -series lineSeries
# e.g for axis :
$chart getOptions -axis X
# e.g for global options :
$chart getOptions -globalOptions ; # no value required
# get all options for 'title' :
$chart getOptions -option title
# output :
id -minversion 5 -validvalue {} -type str|null -default "nothing"
show -minversion 5 -validvalue {} -type bool -default "True"
text -minversion 5 -validvalue {} -type str|null -default "nothing"
link -minversion 5 -validvalue {} -type str|null -default "nothing"
target -minversion 5 -validvalue formatTarget -type str -default "blank"
textStyle -minversion 5 -validvalue {} -type dict|null
color -minversion 5 -validvalue formatColor -type str.t|jsfunc|null -default $color
fontStyle -minversion 5 -validvalue formatFontStyle -type str -default "normal"
fontWeight -minversion 5 -validvalue formatFontWeight -type str.t|num.t|null -default $fontWeight
fontFamily -minversion 5 -validvalue {} -type str -default "sans-serif"
fontSize -minversion 5 -validvalue {} -type num.t|null -default $fontSize
lineHeight -minversion 5 -validvalue {} -type num|null -default "nothing"
width -minversion 5 -validvalue {} -type num -default 100
height -minversion 5 -validvalue {} -type num -default 50
textBorderColor -minversion 5 -validvalue {} -type str|null -default "null"
textBorderWidth -minversion 5 -validvalue {} -type num -default 0
textBorderType -minversion 5 -validvalue formatTextBorderType -type str|num|list.n -default "solid"
textBorderDashOffset -minversion 5 -validvalue {} -type num -default 0
textShadowColor -minversion 5 -validvalue formatColor -type str -default "transparent"
textShadowBlur -minversion 5 -validvalue {} -type num -default 0
textShadowOffsetX -minversion 5 -validvalue {} -type num -default 0
textShadowOffsetY -minversion 5 -validvalue {} -type num -default 0
overflow -minversion 5 -validvalue formatOverflow -type str|null -default "null"
ellipsis -minversion 5 -validvalue {} -type str -default "..."
# ...
subtext -minversion 5 -validvalue {} -type str|null -default "nothing"
sublink -minversion 5 -validvalue {} -type str|null -default "nothing"
...
...
# Following options voluntarily deleted.
- Delete series by index:
$chart Add "lineSeries" -data [list {1 2 3 4}]
$chart Add "barSeries" -data [list {5 6 7 8}]
# Delete bar series :
$chart deleteSeries 1
- Gets json data :
$chart toJSON
- Export chart as HTML fragment :
$chart toHTML ?-template ?...
- Add JSON structure:
$chart AddJSON $struct ?-parent ?... ; # See '# Structure' section
- Capture an image:
$chart SnapShot ?-outfile ?... ; # See '# Image' section
Add extra JS script, variable, etc. :
- Add a JavaScript function :
When permitted, ticklecharts::jsfunc
class can insert a function directly in JSON
data :
# Initializes a new jsfunc Class and insert
# a 'JS function' as argument :
set js [ticklecharts::jsfunc new {
function (value, index) {
return value + ' (C°)';
}
}
]
# Add $js variable to 'formatter' property.
$chart Xaxis -axisLabel [subst {
show "True"
margin 8
formatter $js
showMinLabel "null"
# ...
}]
$chart toJSON
- Output :
"axisLabel": {
"show": true,
"margin": 8,
"formatter": function (value, index) {
return value + ' (C°)';
},
"showMinLabel": null,
// ...
}
[!NOTE]
formatter accepts a javascript function most times but in some casesformatter
supports
string template like this'{b0}: {c0}<br />{b1}: {c1}'
There are three ways to do this :
- Encapsulates the string with braces + quotes :
{"{b0}: {c0}<br />{b1}: {c1}"}
- Use ticklecharts::eString class :
new estr "{b0}: {c0}<br />{b1}: {c1}"
- Replaces by special chars : (Deprecated)
"<0123>b0<0125>: <0123>c0<0125><br /><0123>b1<0125>: <0123>c1<0125>"
Chars | Map |
---|---|
{ | <0123> |
} | <0125> |
[ | <091> |
] | <093> |
- Add script, variable etc. :
Combined with Render
method and -script
property, you can add JavaScript elements in the HTML template file.
-
Depending on where you want to insert them, three optional argument are supported :
-start
: To place your element at the beginning of the file.-end
: To place your element at the end of the file.-header
: To place your element in the file header.
# Adds a variable at the start:
set var [ticklecharts::jsfunc new {
var maskImage = new Image();
maskImage.src = './logo.png';
} -start
]
# Adds a header script:
set header [ticklecharts::jsfunc new {
<script type="text/javascript" src="tcl.js"></script>
} -header
]
# Note: Inserting a script, variable, etc. in the HTML file is
# based on a search for a string in the template if this is not found,
# an error is generated.
$chart Render -title "Example jsfunc class" -script [list [list $var $header]]
- Output :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example jsfunc class</title>
<script type="text/javascript" src="echarts.min.js"></script>
<!-- -header <script>...</script> -->
<script type="text/javascript" src="tcl.js"></script>
</head>
<body>
<div id="main" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart = echarts.init(document.getElementById('main'), null, {renderer: 'canvas'});
// -start script...
var maskImage = new Image();
maskImage.src = './logo.png';
var option = {
"backgroundColor": "rgba(0,0,0,0)",
"color": [
// ...
],
"maskImage": maskImage,
// ...
}
</script>
</body>
</html>
Performance :
Since version 2, some huddle/ehuddle procedures can be replaced by functions written in C with help of critcl.
Critcl package should be available and this command ticklecharts::eHuddleCritcl
should be set to valid Tcl_boolean
value.
You may be processing important data and if you want to gain speed, this command can be useful, below how to use it :
package require ticklecharts
# Load critcl package
# Note : A warning message may be displayed on your console
# if there was a problem compiling or loading critcl package
ticklecharts::eHuddleCritcl True
source examples/candlestick/candlestick_large_scale.tcl ; # dataCount set to 200,000
# | This run (Mac Os Core i7)
# pure Tcl | 25354915 microseconds per iteration
# critcl | 6338728 microseconds per iteration (≃4x faster)
Note
: No advantage to use this command with small data.
Type substitution :
Since version 3.1, two new classes have been introduced. They allow string and list values to be substituted.
In some cases, it is difficult to find the type for a variable, since everything is considered to be a string in Tcl
.
These 2 classes below get around the problem (partly):
- ticklecharts::eString
- ticklecharts::eList
See line_eList.tcl and line and bar mixed
demo to know why this class has been implemented for certain cases.
Since version 3.2.3 when default type is list.d
it can be replaced by list.s
or list.n
ehuddle type.
This improves performance by avoiding the need to scan the list to find the type of data. By example, the default type
for Xaxis.data
is list.d
, this property can be written as follows :
# Note : If you are sure that the X data is of type 'string', you can replace
# -data [list {...}] property by :
$chart Xaxis -data [new elist.s {...}]
Structure :
Since version 3.2.4, it is now possible to construct your own JSON
, and a new eStruct
class has been added
for this purpose. The idea here is to give the user the choice of making their own structure.
# The keys must be typed (str, struct, bool...).
# Be careful, input data is not verified, you have control.
new estruct myStruct {
key1:num "number value"
key2:str "string value"
key3:list.n "list of numbers"
key4:bool "boolean value"
key5:... "..."
}
# Optional argument to 'AddJSON' method:
# '-parent' (with or without index).
# With this optional argument, we can add our structure to a specific location.
$chart AddJSON $myStruct ?-parent ?key1(?index).?key2(?index)
See line_build_your_own_JSON.tcl for a more detailed example.
Image :
Since version 3.2.4, if Chromium
(web browser)is installed, it is possible to capture an image via
chrome devtools protocol. The return type for image is either a
*.(png|svg)file or data in
base64` format.
Dependencies : websocket
package from Tcllib
Arguments available :
args | Description | Default values |
---|---|---|
-address | Local adress | "127.0.0.1" |
-port | Port number | 8888 |
-exe | Full path executable | "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" |
-html | Html fragment | "nothing" |
-renderer | base64, png or svg | "png" |
-outfile | Full path file | "./render.(png|svg)" |
-excludecomponents | Excluded components | "nothing" (List e.g. ['toolbox', 'title', '...'] ) |
-timeout | Time to execute JS function | 400 (milliseconds) |
# Note : Animations must be disabled, which is not the case by default.
$chart SetOptions -animation "False"
# ...
$chart SnapShot -timeout 600 -port 8080 ; # Returns full path '*.png' file
# Example with 'html' fragment on Windows :
#
# Export '$chart' as HTML fragment.
set html [$chart toHTML]
# Note : A full path should be specified if 'msedge.exe' is not included in 'env(PATH)'.
$chart SnapShot -exe "msedge.exe" -html $html -renderer "base64"
# For 'svg' renderer it's important to set the '-renderer' property
# to 'svg' in 'toHTML' method.
set html [$chart toHTML -renderer "svg"]
$chart SnapShot -renderer "svg" -html $html
# ...
[!NOTE]
- A temporary file is created when the command is executed (This may change in future versions of
ticklEcharts
).- Method not supported with 'chart3D' class.
- Highly unstable, depends on the version of
Chromium
installed.
Global variables :
package require ticklecharts
# Set theme with global variable
# Or with class : ticklecharts::(Gridlayout|chart|timeline|chart3D) new -theme "vintage"
set ::ticklecharts::theme "vintage" ; # default "custom"
# Minimum properties:
# Only write values that are defined in the *.tcl file. (Benefit : performance + minifying your HTML files)
# Be careful, properties in the *.tcl file must be implicitly marked.
set ::ticklecharts::minProperties "True" ; # default "False"
# Output 'render.html' full path to stdout.
set ::ticklecharts::htmlstdout "False" ; # default "True"
# Google API Key
# Note : To use the Google map API 'gmap' a valid key is required.
set ::ticklecharts::keyGMAPI "??" ; # Please replace '??' with your own API key.
# Set versions for js script.
# Note : Num version (@X.X.X) should be defined in js path. If no pattern matches, the script path is left unchanged.
set ::ticklecharts::echarts_version "X.X.X" ; # Echarts version
set ::ticklecharts::gl_version "X.X.X" ; # Echarts GL version
set ::ticklecharts::gmap_version "X.X.X" ; # gmap version
set ::ticklecharts::wc_version "X.X.X" ; # wordcloud version
# Verify if a URL exists when Echarts version changed.
set ::ticklecharts::checkURL "True" ; # default "False"
All the above variables can be modified in the ticklecharts.tcl
file.
Examples :
See the examples folder for all demos (from Apache Echarts examples)
# line + bar on same canvas.
package require ticklecharts
# Initializes a new 2D Chart Class.
set chart [ticklecharts::chart new]
# Set options
$chart SetOptions -tooltip {show True trigger "axis" axisPointer {type "cross" crossStyle {color "#999"}}} \
-grid {left "3%" right "4%" bottom "3%" containLabel "True"} \
-legend {}
$chart Xaxis -data [list {"Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"}] \
-axisPointer {type "shadow"}
# Encapsulates the string with braces + quotes or use 'ticklecharts::eString'
# class for 'formatter' property (See '# string template' section).
$chart Yaxis -name "Precipitation" -position "left" -min 0 -max 250 -interval 50 \
-axisLabel {formatter {"{value} ml"}}
$chart Yaxis -name "Temperature" -position "right" -min 0 -max 25 -interval 5 \
-axisLabel [list formatter [new estr "{value} °C"]]
# Add bars series.
$chart Add "barSeries" -name "Evaporation" \
-data [list {2.0 4.9 7.0 23.2 25.6 76.7 135.6 162.2 32.6 20.0 6.4 3.3}]
$chart Add "barSeries" -name "Precipitation" \
-data [list {2.6 5.9 9.0 26.4 28.7 70.7 175.6 182.2 48.7 18.8 6.0 2.3}]
# Add line series.
$chart Add "lineSeries" -name "Temperature" \
-yAxisIndex 1 \
-data [list {2.0 2.2 3.3 4.5 6.3 10.2 20.3 23.4 23.0 16.5 12.0 6.2}]
# Output
$chart Render
# Demo layout with line, bar and pie charts.
set data(0) {1 2 3 4 5}
set data(1) {2 3.6 6 2 10}
# Format label
set js [ticklecharts::jsfunc new {
function (value, index) {
return value + ' (C°)';
},
}]
set line [ticklecharts::chart new]
$line SetOptions -title {text "layout line + bar + pie charts..."} \
-tooltip {show "True"} \
-legend {top "56%" left "20%"}
$line Xaxis -data [list $data(0)] -boundaryGap "False"
$line Yaxis
$line Add "lineSeries" -data [list $data(0)] -areaStyle {} -smooth "True"
$line Add "lineSeries" -data [list $data(1)] -smooth "True"
set bar [ticklecharts::chart new]
$bar SetOptions -legend {top "2%" left "20%"}
$bar Xaxis -data [list {A B C D E}] \
-axisLabel [list show "True" formatter $js]
$bar Yaxis
$bar Add "barSeries" -data [list {50 6 80 120 30}]
$bar Add "barSeries" -data [list {20 30 50 100 25}]
set pie [ticklecharts::chart new]
$pie SetOptions -legend {top "6%" left "65%"}
$pie Add "pieSeries" -name "Access From" -radius [list {"50%" "70%"}] \
-labelLine {show "True"} \
-dataItem {
{value 1048 name "C++"}
{value 300 name "Tcl"}
{value 580 name "Javascript"}
{value 484 name "Python"}
{value 735 name "C"}
}
# Initializes a new 'Gridlayout' Class.
set layout [ticklecharts::Gridlayout new]
# Arrange the different series on the canvas.
$layout Add $bar -bottom "60%" -width "40%" -left "5%"
$layout Add $line -top "60%" -width "40%" -left "5%"
$layout Add $pie -center [list {75% 50%}]
$layout Render
Currently chart and options supported are :
- Global options :
- title
- legend
- grid
- grid3D
- xaxis
- xaxis3D
- yaxis
- yaxis3D
- zaxis3D
- polar
- radiusAxis
- angleAxis
- radar
- dataZoom
- visualMap
- tooltip
- axisPointer
- toolbox
- brush
- geo
- parallel
- parallelAxis
- singleAxis
- timeline
- graphic
- calendar
- dataset
- aria
- globe
- Series :
- line
- line3D
- lines3D
- bar
- bar3D
- pie
- scatter
- scatter3D
- effectScatter
- radar
- tree
- treemap
- sunburst
- boxplot
- candlestick
- heatmap
- map
- parallel
- lines
- graph
- sankey
- surface (3D)
- funnel
- gauge
- pictorialBar
- themeRiver
- custom (see note below)
- wordCloud
[!NOTE]
custom series contains a lot of Javascript codes, I don’t think it’s interesting to write it in this package.
If you are interested, please report to the github issue tracker.
License :
ticklEcharts is covered under the terms of the MIT license.
Change log :
See detailed changes for each release.