Changeset 700167
- Timestamp:
- 04/19/2013 09:25:46 AM (13 years ago)
- Location:
- ipu-chart
- Files:
-
- 2 added
- 7 edited
-
assets/screenshot-1.png (modified) (previous)
-
assets/screenshot-2.png (modified) (previous)
-
assets/screenshot-3.png (modified) (previous)
-
assets/screenshot-4.png (modified) (previous)
-
assets/screenshot-5.png (added)
-
assets/screenshot-6.png (added)
-
trunk/ipu-chart.php (modified) (6 diffs)
-
trunk/js/ipu-chart.js (modified) (16 diffs)
-
trunk/readme.txt (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ipu-chart/trunk/ipu-chart.php
r695096 r700167 3 3 Plugin Name: IPU-Chart 4 4 Plugin URI: https://www.ipublia.com/ipu-chart 5 Description: Creates SVG based charts out of your CSV data. Currently supports bar, pie and line charts.5 Description: Creates SVG based charts out of your CSV data. Currently supports bar, pie, donut and line charts. 6 6 Author: ipublia, Thomas Müller Flury 7 Version: 0. 27 Version: 0.3 8 8 Author URI: https://www.ipublia.com/author/thmufl/ 9 9 Text Domain: ipuchart … … 11 11 */ 12 12 13 function plugin_get_version() { 14 require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); 15 $plugin_data = get_plugin_data( __FILE__ ); 16 $plugin_version = $plugin_data['Name'] . ', Version ' . $plugin_data['Version']; 17 return $plugin_version; 18 } 19 20 // This is the csv tag 13 21 function ipu_csv_func($atts, $content = null) { 14 22 extract(shortcode_atts(array( … … 24 32 } 25 33 34 // This is the chart tag 26 35 function ipu_chart_func($atts) { 27 36 extract(shortcode_atts(array( … … 37 46 'description' => 'Set a description', 38 47 'sort' => 'none', 48 'interpolate' => 'linear', 49 'animate' => 'none', 39 50 'img' => '', 40 51 'debug' => 'false' 41 52 ), $atts)); 42 53 43 return ipu_render_chart($id, $csv, $type, $category, $value, $format, $color, $style, $title, $description, $sort, $img, $debug); 54 return ipu_render_chart($id, $csv, $type, $category, $value, 55 $format, $color, $style, 56 $title, $description, $sort, $interpolate, $animate, 57 $img, $debug, plugin_get_version()); 44 58 } 45 59 60 // This is the table tag 46 61 function ipu_table_func($atts) { 47 62 extract(shortcode_atts(array( … … 60 75 61 76 function ipu_render_csv($id, $content) { 62 63 77 return "<div id='{$id}' class='csv' style='display:none;white-space:pre;'>{$content}</div>"; 64 78 } 65 79 66 function ipu_render_chart($id, $csv, $type, $category, $value, $format, $color, $style, $title, $description, $sort, $i mg, $debug) {80 function ipu_render_chart($id, $csv, $type, $category, $value, $format, $color, $style, $title, $description, $sort, $interpolate, $animate, $img, $debug, $version) { 67 81 return "<figure id='{$id}' class='chart'> 68 82 <script type='text/javascript'> 69 renderChart('{$id}', '{$csv}', '{$type}', '{$category}', '{$value}', '{$format}', 70 '{$color}', '{$style}', '{$title}', '{$description}', '{$sort}', '{$img}', '{$debug}'); 83 renderChart('{$id}', '{$csv}', '{$type}', '{$category}', '{$value}', 84 '{$format}', '{$color}', '{$style}', 85 '{$title}', '{$description}', '{$sort}', '{$interpolate}', '{$animate}', 86 '{$img}', '{$debug}', '{$version}'); 71 87 </script> 72 88 </figure>"; … … 74 90 75 91 function ipu_render_table($id, $csv, $title, $debug) { 76 77 92 return "<table id='{$id}' class='chart-data'> 78 93 <script type='text/javascript'> -
ipu-chart/trunk/js/ipu-chart.js
r695096 r700167 9 9 tooltip; 10 10 11 function toArray(l) { 12 ll = l.split(','); 13 for(var i=0; i<ll.length; i++) { 14 ll[i] = ll[i].trim(); 15 } 16 return ll; 17 } 18 11 19 function parserFor(format) { 12 format = format.t oLowerCase().trim();20 format = format.trim(); 13 21 if(format == "i" || format == "integer") return parseInt; 14 22 if(format == "f" || format == "float") return parseFloat; 15 23 if(format == "s" || format == "string") return function(s) { return s; }; 16 if(format == "yyyy-mm-dd" || format == "date") return d3.time.format("%Y-%m-%d").parse; 24 25 if(format == "yyyymmdd" || format == "d" || format == "date") return d3.time.format("%Y%m%d").parse; 26 if(format == "yyyy-mm-dd") return d3.time.format("%Y-%m-%d").parse; 17 27 if(format == "yy-mm-dd") return d3.time.format("%y-%m-%d").parse; 18 28 if(format == "yyyy/mm/dd") return d3.time.format("%Y/%m/%d").parse; … … 20 30 if(format == "dd.mm.yyyy") return d3.time.format("%d.%m.%Y").parse; 21 31 if(format == "dd.mm.yy") return d3.time.format("%d.%m.%y").parse; 32 22 33 return d3.time.format(format).parse; 23 34 } 24 35 25 36 function scaleFor(format) { 26 format = format.t oLowerCase().trim();37 format = format.trim(); 27 38 if(format == "i" || format == "integer") return d3.scale.linear(); 28 39 if(format == "f" || format == "float") return d3.scale.linear(); … … 30 41 return d3.time.scale(); 31 42 } 32 33 function renderChart(id, csv, type, category, value, format, color, style, title, description, sort, img, debug) { 34 35 var debug = (debug.toLowerCase() == "true"); 36 if(debug) { console.log("---------- START RENDERING CHART (" + id + ", " + csv + ", " + type + ") ----------"); }; 43 44 function parseData(data, category, value, format, debug) { 45 // Parse the datatypes 46 for(var i = 0; i < data.length; i++) { 47 for(var j = 0; j < category.length; j++) { 48 data[i][category[j]] = parserFor(format[j])(data[i][category[j]]); 49 } 50 for(var j = 0; j < value.length; j++) { 51 data[i][value[j]] = parserFor(format[category.length + j])(data[i][value[j]]); 52 } 53 } 54 return data; 55 } 56 57 function colorScale(color) { 58 if(color[0].toLowerCase().trim() == "auto") { 59 color = d3.scale.category20(); 60 } else { 61 color=d3.scale.ordinal().range(color); 62 } 63 return color; 64 } 65 66 function renderNoSvgSupport(figure, img) { 67 68 figure.select("svg").remove(); 69 70 if(img && img.trim() != "") { 71 image = figure.append("img") 72 .attr("src", img) 73 .attr("width", parseInt(figure.style("width"))) 74 .attr("height", parseInt(figure.style("height")) - 40); 75 } else { 76 figure.append("p") 77 .text("Sorry, can't display the chart. Use a newer, SVG enabled browser.") 78 .attr("style", "color: red;"); 79 figure.attr("style", "border: 1px solid lightgray; padding: 1em;"); 80 } 81 } 82 83 function renderError(figure, error) { 84 figure.select("svg").remove(); 85 figure.append("p") 86 .text(error) 87 .attr("style", "color: red;"); 88 figure.attr("style", "border: 1px solid lightgray; padding: 1em;"); 89 return false; 90 } 91 92 function createFigureElement(id, title, description, style) { 93 var figure = d3.select('#' + id); 94 figure.attr("style", style); 95 96 var svg = figure.append("svg"); 97 98 svg.append("g") 99 .attr("class", "meta") 100 .append("title").text(title) 101 .append("description").text(description); 102 103 figure.append("figcaption").text(title); 104 105 var width = parseInt(figure.style("width")), 106 height = parseInt(figure.style("height")) - parseInt(figure.select("figcaption").style("height")) - 20; 107 108 svg.attr("viewBox", "0 0 " + width + " " + height) 109 .attr("preserveAspectRatio", "xMidYMid meet") 110 .attr("width", width) 111 .attr("height", height) 112 .append("g") 113 .attr("class", "main"); 114 115 return figure; 116 } 117 118 function createTooltip() { 119 if(tooltip == null) { 120 tooltip = d3.select("body").append("div") 121 .attr("class", "iputooltip") 122 .style("opacity", 0.0) 123 .style("width", function() {return screen.width > 320 ? "260px" : "160px"; }) 124 .html("<p>tooltip</p>") 125 .on("touchstart", hideTooltip); 126 } 127 return tooltip; 128 } 129 130 function renderChart(id, csv, type, category, value, format, color, style, title, description, sort, interpolate, animate, img, debug, version) { 131 132 debug = (debug.toLowerCase() == "true"); 133 37 134 if(debug) { 38 135 … … 42 139 + "\n\tSVG support: " + svgSupport 43 140 + "\n\tscreen width/height: " + screen.width + "px/" + screen.height + "px"); 141 142 console.log("PLUGIN: " 143 + "\n\t" + version); 44 144 45 145 … … 56 156 + "\n\tdescription: " + description 57 157 + "\n\tsort: " + sort 158 + "\n\tinterpolate: " + interpolate 159 + "\n\tanimate: " + animate 58 160 + "\n\timg: " + img 59 161 + "\n\tdebug: " + debug); 60 162 } 61 163 62 if(!svgSupport) { 63 64 var figure = d3.select('#' + id); 65 figure.attr("style", style); 66 67 if(img && img.trim() != "") { 68 var width = parseInt(figure.style("width")), 69 height = parseInt(figure.style("height")) - 40; 70 71 figure.append("figcaption").text(title); 72 image = figure.append("img") 73 .attr("src", img) 74 .attr("width", width) 75 .attr("height", height); 76 } else { 77 figure.append("p").text("Chart: '" + title + "'"); 78 figure.append("p") 79 .text("Please use a newer, SVG capable browser to view the chart.") 80 .attr("style", "color: red; "); 81 figure.attr("style", "border: 1px solid lightgray; padding: 1em;"); 82 } 83 84 } else { 85 load(id, csv, type, category, value, format, color, style, title, description, sort, img, debug); 86 } 87 } 88 89 function load(id, csv, type, category, value, format, color, style, title, description, sort, img, debug) { 90 164 var figure = createFigureElement(id, title, description, style); 165 166 if(!svgSupport) return renderNoSvgSupport(figure, img); 167 168 createTooltip(); 169 170 category = toArray(category); 171 value = toArray(value); 172 format = toArray(format); 173 color = toArray(color); 174 animate = toArray(animate); 175 176 if(animate[0] == "slow") animate = ["5000", "linear"]; 177 else if(animate[0] == "medium") animate = ["2000", "linear"]; 178 else if(animate[0] == "fast") animate = ["1000", "linear"]; 179 91 180 if((/^#/).test(csv)) { 92 div = d3.select(csv), 93 data = d3.csv.parse(div.text()); 94 if(debug) { console.log("LOADING DATA SYNC (" + csv + ")"); console.log(data); } 95 render(id, data, type, category, value, format, color, style, title, description, sort, img, debug); 181 if(d3.select(csv).empty()) { 182 return renderError(figure, "The csv '" + csv + "' does not exist in this document."); 183 } 184 data = d3.csv.parse(d3.select(csv).text()); 185 if(debug) { console.log("Loaded data (sync): "); console.log(data) }; 186 187 render(figure, data, type, category, value, format, color, sort, interpolate, animate, debug); 188 96 189 } else { 97 190 d3.csv(csv, function(error, data) { 98 if(debug) { console.log("LOADING DATA ASYNC (" + csv + ")"); console.log(data); } 99 if(error) return console.warn(error); 100 render(id, data, type, category, value, format, color, style, title, description, sort, img, debug); 101 }); 191 if(error) { 192 console.warn("There was an error loading the data: " + error); 193 return renderError(figure, "There was an error loading the data: " + csv); 194 } 195 if(debug) { console.log("Loaded data (async): "); console.log(data) }; 196 render(figure, data, type, category, value, format, color, sort, interpolate, animate, debug); 197 }); 102 198 } 103 } 104 105 function render(id, data, type, category, value, format, color, style, title, description, sort, img, debug) { 106 if(debug) { console.log("RENDER (" + id + ")"); }; 107 108 formats = format.split(','); 109 for(var i=0; i<formats.length; i++) { 110 formats[i] = formats[i].trim(); 111 } 112 113 if(debug) { console.log("FORMATS: " + formats); } 114 115 if(color.toLowerCase().trim() == "auto") { 116 colors = d3.scale.category20(); 117 } else { 118 colors = color.split(','); 119 for(var i=0; i<colors.length; i++) { 120 colors[i] = colors[i].trim(); 121 } 122 colors=d3.scale.ordinal().range(colors); 123 } 124 125 if(debug) { console.log("COLOR: " + color); } 126 127 catParser = parserFor(formats[0]); 128 valParser = parserFor(formats[1]); 129 130 /* Not supported by IE 131 data.forEach(function(d) { 132 d[category] = catParser(d[category]); 133 d[value] = valParser(d[value]); 134 }); 135 */ 136 137 for(var i=0; i<data.length; i++) { 138 data[i][category] = catParser(data[i][category]); 139 data[i][value] = valParser(data[i][value]); 140 } 141 142 if(debug) { console.log("PARSED DATA: "); console.log(data); } 143 144 var figure = d3.select('#' + id); 145 146 var svg = figure.append("svg"), 147 meta = svg.append("g").attr("class", "meta"); 148 //chart = svg.append("g").attr("class", "main"); 149 150 var figcaption = figure.append("figcaption").text(title); 151 meta.append("title").text(title); 152 meta.append("description").text(description); 153 figure.attr("style", style); 154 155 var width = parseInt(figure.style("width")), 156 height = parseInt(figure.style("height")) - parseInt(figcaption.style("height")) - 20; 157 158 if(debug) { console.log("SVG \n\twidth: " + width + "\n\theight: " + height); } 159 160 svg.attr("viewBox", "0 0 " + width + " " + height) 161 .attr("preserveAspectRatio", "xMidYMid meet") 162 .attr("width", width) 163 .attr("height", height); 164 165 if(tooltip == null) { 166 tooltip = d3.select("body").append("div") 167 .attr("class", "iputooltip") 168 .style("opacity", 0.0) 169 .style("width", function() {return screen.width > 320 ? "260px" : "160px"; }) 170 .html("<p>tooltip</p>") 171 .on("touchstart", hideTooltip); 172 } 173 199 } 200 201 function render(figure, data, type, category, value, format, color, sort, interpolate, animate, debug) { 202 203 data = parseData(data, category, value, format, debug); 204 174 205 if(type.toLowerCase().trim() == "bar") 175 renderBar( svg, width, height, data, category, value, formats, colors, debug);206 renderBar(figure, data, category, value, format, color, sort, interpolate, animate, debug); 176 207 177 208 else if(type.toLowerCase().trim() == "bar.horizontal") 178 renderBarHorizontal( svg, width, height, data, category, value, formats, colors, debug);209 renderBarHorizontal(figure, data, category, value, format, color, sort, interpolate, animate, debug); 179 210 180 211 else if(type.toLowerCase().trim() == "pie") 181 renderPie(svg, width, height, data, category, value, formats, colors, debug); 212 renderPie(figure, data, category, value, format, color, sort, interpolate, animate, debug); 213 214 else if(type.toLowerCase().trim() == "donut") 215 renderDonut(figure, data, category, value, format, color, sort, interpolate, animate, debug); 182 216 183 217 else if(type.toLowerCase().trim() == "line") 184 renderLine(svg, width, height, data, category, value, formats, colors, debug); 185 } 186 187 function renderTable(id, csv, title, debug) { 188 var debug = (debug.toLowerCase() == "true"); 189 if(debug) { console.log("---------- START RENDER TABLE ----------" 190 + "\n\tid: " + id 191 + "\n\tcsv: " + csv 192 + "\n\ttitle: " + title 193 + "\n\tdebug: " + debug); } 194 195 var div = d3.select(csv), 196 data = d3.csv.parse(div.text()); 197 198 if(debug) { console.log("LOADING DATA ASYNC (" + csv + ")"); console.log(data); } 199 200 var columns = d3.keys(data[0]); 201 202 var table = d3.select('#' + id), 203 caption = table.append("caption"), 204 thead = table.append("thead"), 205 tbody = table.append("tbody"); 206 207 caption.text(title); 208 209 // append the header row 210 thead.append("tr") 211 .selectAll("th") 212 .data(columns) 213 .enter() 214 .append("th") 215 .text(function(column) { return column; }); 216 217 // create a row for each object in the data 218 var rows = tbody.selectAll("tr") 219 .data(data) 220 .enter() 221 .append("tr"); 222 223 // create a cell in each row for each column 224 var cells = rows.selectAll("td") 225 .data(function(row) { 226 return columns.map(function(column) { 227 return {column: column, value: row[column]}; 228 }); 229 }) 230 .enter() 231 .append("td") 232 .text(function(d) { return d.value; }); 233 234 if(debug) { console.log("END RENDER TABLE"); } 235 } 236 237 function renderBar(svg, width, height, data, category, value, formats, colors, debug) { 238 if(debug) { console.log("START RENDER BAR") }; 239 240 var color = d3.scale.ordinal().range(colors); 241 218 renderLine(figure, data, category, value, format, color, sort, interpolate, animate, debug); 219 220 else if(type.toLowerCase().trim() == "line.multi") 221 renderLineMulti(figure, data, category, value, format, color, sort, interpolate, animate, debug); 222 } 223 224 function renderLine(figure, data, category, value, format, color, sort, interpolate, animate, debug) { 225 if(debug) { console.log("START RENDER LINE"); } 226 227 var color = colorScale(color); 228 229 var svg = figure.select("svg"); 230 242 231 var margin = {top: 20, right: 20, bottom: 40, left: 80}, 243 width = width- margin.left - margin.right,244 height = height- margin.top - margin.bottom;245 246 var x = scaleFor(formats[0])247 .range RoundBands([0, width], .1);248 249 var y = scaleFor(format s[1])232 width = parseInt(svg.attr("width")) - margin.left - margin.right, 233 height = parseInt(svg.attr("height")) - margin.top - margin.bottom; 234 235 var x = scaleFor(format[0]) 236 .range([0, width]); 237 238 var y = scaleFor(format[1]) 250 239 .range([height, 0]); 251 240 252 241 var xAxis = d3.svg.axis() 253 242 .scale(x) 254 .orient("bottom"); 243 .orient("bottom") 244 .tickSize(height); 255 245 256 246 var yAxis = d3.svg.axis() … … 259 249 .tickSize(width); 260 250 251 var line = d3.svg.line() 252 .interpolate(interpolate) 253 .x(function(d) { return x(d[category]); }) 254 .y(function(d) { return y(d[value]); }); 255 256 x.domain(d3.extent(data, function(d) { return d[category]; })); 257 y.domain(d3.extent(data, function(d) { return d[value]; })); 258 259 var chart = svg.append("g") 260 .attr("class", "chart") 261 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 262 263 chart.append("g") 264 .attr("class", "x axis") 265 .attr("transform", "translate(0," + 0 + ")") 266 .call(xAxis); 267 268 chart.append("g") 269 .attr("class", "y axis") 270 .attr("transform", "translate(" + width + ", 0)") 271 .call(yAxis); 272 273 chart.append("path") 274 .datum(data) 275 .attr("class", "line") 276 .style("stroke", function(d) { return color(d[category]); }) 277 .attr("d", line); 278 279 chart.selectAll(".dot") 280 .data(data) 281 .enter().append("circle") 282 .attr("class", "dot") 283 .attr("r", 5) 284 .attr("cx", function(d) { return x(d[category]); }) 285 .attr("cy", function(d) { return y(d[value]); }) 286 .attr("opacity", 0.0); 287 288 if(touch_device) { 289 d3.selectAll(".dot") 290 .on("touchstart", showTooltip); 291 } else { 292 d3.selectAll(".dot") 293 .on("mouseover", showTooltip) 294 .on("mousemove", moveTooltip) 295 .on("mouseout", hideTooltip); 296 } 297 if(debug) { console.log("END RENDER LINE") }; 298 } 299 300 function renderBar(figure, data, category, value, format, color, sort, interpolate, animate, debug) { 301 if(debug) { console.log("START RENDER BAR") }; 302 303 var color = colorScale(color); 304 305 var svg = figure.select("svg"); 306 307 var margin = {top: 20, right: 20, bottom: 40, left: 80}, 308 width = parseInt(svg.attr("width")) - margin.left - margin.right, 309 height = parseInt(svg.attr("height")) - margin.top - margin.bottom; 310 311 var x = scaleFor(format[0]) 312 .rangeRoundBands([0, width], .1); 313 314 var y = scaleFor(format[1]) 315 .range([height, 0]); 316 317 var xAxis = d3.svg.axis() 318 .scale(x) 319 .orient("bottom"); 320 321 var yAxis = d3.svg.axis() 322 .scale(y) 323 .orient("left") 324 .tickSize(width); 325 261 326 x.domain(data.map(function(d) { return d[category]; })); 262 327 y.domain([0, d3.max(data, function(d) { return d[value]; })]); 263 264 svg.attr("width", width + margin.left + margin.right)265 .attr("height", height + margin.top + margin.bottom);266 328 267 329 var chart = svg.append("g") … … 287 349 .attr("y", function(d) { return y(d[value]); }) 288 350 .attr("height", function(d) { return height - y(d[value]); }) 289 .style("fill", function(d) { return color s(d[category]); })351 .style("fill", function(d) { return color(d[category]); }) 290 352 .style("opacity", defaultOpacity); 291 353 354 function startAnimation() { 355 if(animate[0] != "none") { 356 duration = +animate[0]; 357 ease = animate[1] != null ? animate[1] : "linear"; 358 if(debug) console.log("Starting animation, figure: " + figure.attr("id") + ", duration: " + duration + ", ease: " + ease); 359 360 chart.selectAll(".bar") 361 .attr("y", y(0)) 362 .attr("height", 0) 363 .transition() 364 .ease(ease) 365 .delay(function(d, i) { return duration/2 + i * duration; }) 366 .duration(duration) 367 .attr("y", function(d) { return y(d[value]); }) 368 .attr("height", function(d) { return height - y(d[value]); }); 369 } 370 } 371 372 292 373 if(touch_device) { 293 374 d3.selectAll(".bar") 294 375 .on("touchstart", showTooltip); 376 377 figure.selectAll("svg") 378 .on("touchstart", startAnimation); 379 295 380 } else { 296 381 d3.selectAll(".bar") … … 298 383 .on("mousemove", moveTooltip) 299 384 .on("mouseout", hideTooltip); 385 386 figure.selectAll("svg") 387 .on("mousedown", startAnimation); 300 388 } 301 389 … … 304 392 } 305 393 306 function renderBarHorizontal( svg, width, height, data, category, value, formats, colors, debug) {394 function renderBarHorizontal(figure, data, category, value, format, color, sort, interpolate, animate, debug) { 307 395 if(debug) { console.log("START RENDER BAR HORIZONTAL") }; 308 396 309 var color = d3.scale.ordinal().range(colors); 310 397 var color = colorScale(color); 398 399 data = data.reverse(); 400 401 var svg = figure.select("svg"); 402 311 403 var margin = {top: 20, right: 20, bottom: 40, left: 80}, 312 width = width- margin.left - margin.right,313 height = height- margin.top - margin.bottom;314 315 var x = scaleFor(format s[1])404 width = parseInt(svg.attr("width")) - margin.left - margin.right, 405 height = parseInt(svg.attr("height")) - margin.top - margin.bottom; 406 407 var x = scaleFor(format[1]) 316 408 .range([width, 0]); 317 409 318 var y = scaleFor(format s[0])410 var y = scaleFor(format[0]) 319 411 .rangeRoundBands([0, height], .1); 320 412 … … 330 422 y.domain(data.map(function(d) { return d[category]; })); 331 423 x.domain([d3.max(data, function(d) { return d[value]; }), 0]); 332 333 svg.attr("width", width + margin.left + margin.right)334 .attr("height", height + margin.top + margin.bottom);335 424 336 425 var chart = svg.append("g") … … 355 444 .attr("height", y.rangeBand()) 356 445 .attr("width", function(d) { return x(d[value]); }) 357 .style("fill", function(d) { return color s(d[category]); })446 .style("fill", function(d) { return color(d[category]); }) 358 447 .style("opacity", defaultOpacity); 359 448 449 function startAnimation() { 450 if(animate[0] != "none") { 451 duration = +animate[0]; 452 ease = animate[1] != null ? animate[1] : "linear"; 453 if(debug) console.log("Starting animation, figure: " + figure.attr("id") + ", duration: " + duration + ", ease: " + ease); 454 455 var bars = chart.selectAll(".bar"); 456 bars 457 .attr("width", 0) 458 .transition() 459 .ease(ease) 460 .delay(function(d, i) { return duration/2 + (bars[0].length-i) * duration; }) 461 .duration(duration) 462 .attr("width", function(d) { return x(d[value]); }); 463 } 464 } 465 360 466 if(touch_device) { 361 467 d3.selectAll(".bar") 362 468 .on("touchstart", showTooltip); 469 470 figure.selectAll("svg") 471 .on("touchstart", startAnimation); 472 363 473 } else { 364 474 d3.selectAll(".bar") … … 366 476 .on("mousemove", moveTooltip) 367 477 .on("mouseout", hideTooltip); 478 479 figure.selectAll("svg") 480 .on("mousedown", startAnimation); 368 481 } 482 369 483 if(debug) { console.log("END RENDER BAR HORIZONTAL") }; 370 } 371 372 function renderPie( svg, width, height, data, category, value, formats, colors, debug) {484 } 485 486 function renderPie(figure, data, category, value, format, color, sort, interpolate, animate, debug) { 373 487 if(debug) { console.log("START RENDER PIE") }; 374 488 489 var color = colorScale(color); 490 491 var svg = figure.select("svg"); 492 493 var margin = {top: 0, right: 20, bottom: 0, left: 0}, 494 width = parseInt(svg.attr("width")) - margin.left - margin.right, 495 height = parseInt(svg.attr("height")) - margin.top - margin.bottom; 496 375 497 var radius = Math.min(width, height) / 2; 376 377 var color = d3.scale.ordinal().range(colors);378 498 379 499 var arc = d3.svg.arc() … … 397 517 g.append("path") 398 518 .attr("d", arc) 399 .style("fill", function(d) { return color s(d.data[category]); });519 .style("fill", function(d) { return color(d.data[category]); }); 400 520 401 521 g.append("text") … … 416 536 417 537 if(debug) { console.log("END RENDER PIE") }; 418 } 419 420 function renderLine(svg, width, height, data, category, value, formats, colors, debug) { 421 if(debug) { console.log("START RENDER LINE"); } 422 423 var margin = {top: 20, right: 20, bottom: 40, left: 80}, 424 width = width - margin.left - margin.right, 425 height = height - margin.top - margin.bottom; 426 427 var x = scaleFor(formats[0]) 428 .range([0, width]); 429 430 var y = scaleFor(formats[1]) 431 .range([height, 0]); 432 433 var xAxis = d3.svg.axis() 434 .scale(x) 435 .orient("bottom") 436 .tickSize(height); 437 438 var yAxis = d3.svg.axis() 439 .scale(y) 440 .orient("left") 441 .tickSize(width);; 442 443 var line = d3.svg.line() 444 .x(function(d) { return x(d[category]); }) 445 .y(function(d) { return y(d[value]); }); 446 447 x.domain(d3.extent(data, function(d) { return d[category]; })); 448 y.domain(d3.extent(data, function(d) { return d[value]; })); 449 450 svg.attr("width", width + margin.left + margin.right) 451 .attr("height", height + margin.top + margin.bottom); 452 538 } 539 540 function renderDonut(figure, data, category, value, format, color, sort, interpolate, animate, debug) { 541 if(debug) { console.log("START RENDER DONUT") }; 542 543 var color = colorScale(color); 544 545 var svg = figure.select("svg"); 546 547 var margin = {top: 0, right: 20, bottom: 0, left: 0}, 548 width = parseInt(svg.attr("width")) - margin.left - margin.right, 549 height = parseInt(svg.attr("height")) - margin.top - margin.bottom; 550 551 var radius = Math.min(width, height) / 2; 552 553 var arc = d3.svg.arc() 554 .outerRadius(radius - 5) 555 .innerRadius((radius-5) * .6); 556 557 var pie = d3.layout.pie() 558 .sort(null) 559 .value(function(d) { return d[value]; }); 560 453 561 var chart = svg.append("g") 454 562 .attr("class", "chart") 455 .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 456 457 chart.append("g") 458 .attr("class", "x axis") 459 .attr("transform", "translate(0," + 0 + ")") 460 .call(xAxis); 461 462 chart.append("g") 463 .attr("class", "y axis") 464 .attr("transform", "translate(" + width + ", 0)") 465 .call(yAxis); 466 467 chart.append("path") 468 .datum(data) 469 .attr("class", "line") 470 .style("stroke", function(d) { return colors(d[category]); }) 471 .attr("d", line); 472 473 chart.selectAll(".dot") 474 .data(data) 475 .enter().append("circle") 476 .attr("class", "dot") 477 .attr("r", 5) 478 .attr("cx", function(d) { return x(d[category]); }) 479 .attr("cy", function(d) { return y(d[value]); }) 480 .attr("opacity", 0.0); 563 .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 564 565 var g = chart.selectAll(".arc") 566 .data(pie(data)) 567 .enter().append("g") 568 .attr("class", "arc") 569 .style("opacity", defaultOpacity); 570 571 g.append("path") 572 .attr("d", arc) 573 .style("fill", function(d) { return color(d.data[category]); }); 574 575 g.append("text") 576 .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; }) 577 .attr("dy", ".35em") 578 .style("text-anchor", "middle") 579 .text(function(d) { return d.data[category]; }); 481 580 482 581 if(touch_device) { 483 d3.selectAll(". dot")484 .on("touchstart", showTooltip); 582 d3.selectAll(".arc") 583 .on("touchstart", showTooltip); 485 584 } else { 486 d3.selectAll(". dot")585 d3.selectAll(".arc") 487 586 .on("mouseover", showTooltip) 488 587 .on("mousemove", moveTooltip) 489 .on("mouseout", hideTooltip); 588 .on("mouseout", hideTooltip); 490 589 } 491 if(debug) { console.log("END RENDER LINE") }; 590 591 if(debug) { console.log("END RENDER DONUT") }; 592 } 593 594 function renderTable(id, csv, title, debug) { 595 var debug = (debug.toLowerCase() == "true"); 596 if(debug) { console.log("START RENDER TABLE" 597 + "\n\tid: " + id 598 + "\n\tcsv: " + csv 599 + "\n\ttitle: " + title 600 + "\n\tdebug: " + debug); } 601 602 var div = d3.select(csv), 603 data = d3.csv.parse(div.text()); 604 605 if(debug) { console.log("Loading data async (" + csv + ")"); console.log(data); } 606 607 var columns = d3.keys(data[0]); 608 609 var table = d3.select('#' + id), 610 caption = table.append("caption"), 611 thead = table.append("thead"), 612 tbody = table.append("tbody"); 613 614 caption.text(title); 615 616 // append the header row 617 thead.append("tr") 618 .selectAll("th") 619 .data(columns) 620 .enter() 621 .append("th") 622 .text(function(column) { return column; }); 623 624 // create a row for each object in the data 625 var rows = tbody.selectAll("tr") 626 .data(data) 627 .enter() 628 .append("tr"); 629 630 // create a cell in each row for each column 631 var cells = rows.selectAll("td") 632 .data(function(row) { 633 return columns.map(function(column) { 634 return {column: column, value: row[column]}; 635 }); 636 }) 637 .enter() 638 .append("td") 639 .text(function(d) { return d.value; }); 640 641 if(debug) { console.log("END RENDER TABLE"); } 492 642 } 493 643 … … 565 715 .style("opacity", defaultOpacity); 566 716 717 d3.selectAll(".serie").transition() 718 .duration(200) 719 .style("opacity", defaultOpacity); 720 567 721 d3.selectAll(".dot").transition() 568 722 .duration(200) … … 576 730 d3.event.preventDefault(); 577 731 }; 578 -
ipu-chart/trunk/readme.txt
r695101 r700167 1 1 === Plugin Name === 2 2 Contributors: thmufl 3 Tags: chart, diagram, svg, csv, excel, numbers, bar chart, pie chart, line chart 3 Tags: chart, diagram, svg, csv, excel, numbers, bar chart, pie chart, line chart, animation 4 4 Requires at least: 3.0.1 5 5 Tested up to: 3.5.1 6 Stable tag: 0. 26 Stable tag: 0.3 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 9 10 Creates SVG based barcharts out of your CSV data. A powerful, easy to use shortcode.10 Creates SVG based, animated bar, pie, donut and line charts out of your CSV data. A powerful, easy to use shortcode. 11 11 12 12 == Description == 13 13 14 IPU-Chart is an easy to use shortcode that creates SVG based bar, pie and line charts out of your CSV data.14 IPU-Chart is an easy to use shortcode that creates SVG based bar, pie, donut and line charts out of your CSV data. 15 15 16 The plugin takes a csv file (Texteditor, Excel, Numbers etc.) and displays it as a chart. IPU-Chart is based on SVG andworks perfectly on large computer screens as well as on tablets and smaller mobile screens. For browsers that do not support SVG an alternative image can be set.16 The plugin takes a csv file (Texteditor, Excel, Numbers etc.) and displays it as a chart. IPU-Chart is based on [SVG](http://www.w3.org/TR/SVG/) and [D3](http://d3js.org/). It works perfectly on large computer screens as well as on tablets and smaller mobile screens. For browsers that do not support SVG an alternative image can be set. 17 17 18 18 = Features = 19 19 20 * Create bar, pie and line charts20 * Create bar, pie, donut and line charts 21 21 * Enter the csv data directy in you blog or page 22 * Loadcsv data from a remote location22 * Or load the csv data from a remote location 23 23 * Create multiple views of the csv data 24 * Animated tooltip for chart details (see screenshots) 24 * Tooltip for chart details (see screenshots) 25 * Animated bar charts 25 26 * Define colors and number formats of the chart 26 27 * Create an additional table view of the csv data … … 44 45 [chart id='chart0' 45 46 csv='#popdata' 46 type='bar | bar.horizontal | pie | line'47 type='bar | bar.horizontal | pie | donut | line' 47 48 category='Country' 48 49 value='Population' … … 52 53 title='Top five most populous countries of the world...' 53 54 description='The top five most populous countries of the world...' 54 sort='Population" 55 sort='Population' 56 interpolate='cardinal' 57 animate='medium' 55 58 img='http://www.example.com/chart0.png' 56 59 debug='false'] … … 92 95 2. Horizontal bar chart example 93 96 3. Pie Chart example 94 4. Line chart example 97 4. Donut Chart example 98 5. Line chart example 99 6. Interpolated line chart example 95 100 96 101 == Changelog == … … 108 113 * Changes in format definitions 109 114 115 = 0.3 = 116 * Donut charts added 117 * Attribute 'interpolate' added 118 * Attribute 'animate' added 119 * Enhanced error handling when loading csv data 120 110 121 == Upgrade Notice == 111 122 112 123 = 0.2 = 113 This version adds support for pie- and line-charts. Furthermore formats for dates, integers and floats can be specified. 124 This version adds support for pie and line charts. Furthermore formats for dates, integers and floats can be specified. 125 126 = 0.3 = 127 This version adds support for donut charts. Line chars can be interpolated. Bar charts can be animated (click or tap the bar charts to start the animation).
Note: See TracChangeset
for help on using the changeset viewer.