Minor - avoiding PHP warnings, cleaning some code see #1791

skala
Julio Montoya 13 years ago
parent 520502c41d
commit 8416176965
  1. 8
      main/admin/skills_import.php
  2. 9
      main/admin/skills_wheel.php
  3. 252
      main/inc/lib/javascript/coffeewheel/wheel.js
  4. 7
      main/inc/lib/skill.lib.php
  5. 14
      main/template/default/skill/skill_wheel.tpl

@ -14,7 +14,6 @@ $cidReset = true;
require '../inc/global.inc.php';
require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php';
require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php';
require_once api_get_path(LIBRARY_PATH).'classmanager.lib.php';
require_once api_get_path(LIBRARY_PATH).'import.lib.php';
function validate_data($skills) {
@ -282,16 +281,13 @@ if ($count_fields > 0) {
$i++;
}
}
?>
<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
<blockquote>
<pre>
<b>id</b>;<b>parent_id</b>;<b>name</b>;<b>description</b><br />
<b>n</b>;<b>m</b>;<b>xxx</b>;xxx<br />
<b>id</b>;<b>parent_id</b>;<b>name</b>;<b>description</b>
<b>2</b>;<b>0</b>;<b>Chamilo Expert</b>;Chamilo is an open source LMS;<br />
</pre>
</blockquote>
<!--p><?php echo get_lang('XMLMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>

@ -22,6 +22,7 @@ if (api_get_setting('allow_skills_tool') != 'true') {
//Adds the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_js('d3.v2.min.js');
$htmlHeadXtra[] = api_get_js('coffeewheel/wheel.js');
$skill = new Skill();
$type = 'edit'; //edit
@ -31,16 +32,14 @@ $type = 'edit'; //edit
//$html = $skill_visualizer->return_html();
//$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?1=1';
$tpl = new Template(null, false, false);
//$tpl->assign('url', $url);
//$tpl->assign('html', $html);
$tpl->assign('html', api_get_js('coffeewheel/wheel.js'));
//$tpl->assign('skill_visualizer', $skill_visualizer);
//$tpl->assign('js', $skill_visualizer->return_js());
//$tpl->assign('js', api_get_js('coffeewheel/wheel.js'));
//
$content = $tpl->fetch('default/skill/skill_wheel.tpl');
$tpl->assign('content', $content);
$tpl->display_no_layout_template();
$tpl->display_no_layout_template();

@ -1,6 +1,8 @@
/* Define constants and size of the wheel */
/** Total width of the wheel (also counts for the height) */
var w = 800,
/** Total width of the wheel (also counts for the height) */
$(document).ready(function() {
var w = 800,
h = w,
r = w / 2,
/** x/y positionning of the center of the wheel */
@ -12,148 +14,190 @@ var w = 800,
duration = 1000,
/** Levels to show */
l = 3;
/* Locate the #div id element */
var div = d3.select("#vis");
/* Remove the image (make way for the dynamic stuff */
div.select("img").remove();
/* Append an element "svg" to the #vis section */
var vis = div.append("svg")
/* Locate the #div id element */
var div = d3.select("#vis");
/* Remove the image (make way for the dynamic stuff */
div.select("img").remove();
/* Append an element "svg" to the #vis section */
var vis = div.append("svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("g")
.attr("transform", "translate(" + (r + p) + "," + (r/1.5 + p) + ")");
/* ...update translate variables to change coordinates of wheel's center */
/* Add a small label to help the user */
div.append("p")
/* ...update translate variables to change coordinates of wheel's center */
/* Add a small label to help the user */
div.append("p")
.attr("id", "intro")
.text("Click to zoom!");
/* Generate the partition layout */
var partition = d3.layout.partition()
/* Generate the partition layout */
var partition = d3.layout.partition()
.sort(null)
/** Value here seems to be a calculation of the size of the elements
depending on the level of depth they're at. Changing it makes
elements pass over the limits of others... */
.value(function(d) { return 5.8 - d.depth; });
/* Generate an arc which will define the whole wheel context */
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, d.y ? y(d.y) : d.y); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
/* ...adding "+1" to "y" function's params is really funny */
/* Exexute the calculation based on a JSON file provided */
/*d3.json("wheel.json", function(json) {*/
/** Get the JSON list of skills and work on it */
d3.json("skills.json.php", function(json) {
/** Define the list of nodes based on the JSON */
var nodes = partition.nodes({children: json});
depending on the level of depth they're at. Changing it makes
elements pass over the limits of others... */
.value(function(d) {
return 5.8 - d.depth;
});
/* Generate an arc which will define the whole wheel context */
var arc = d3.svg.arc()
.startAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
})
.endAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
})
.innerRadius(function(d) {
return Math.max(0, d.y ? y(d.y) : d.y);
})
.outerRadius(function(d) {
return Math.max(0, y(d.y + d.dy));
});
/* ...adding "+1" to "y" function's params is really funny */
/* Exexute the calculation based on a JSON file provided */
/*d3.json("wheel.json", function(json) {*/
/** Get the JSON list of skills and work on it */
d3.json("skills.json.php", function(json) {
/** Define the list of nodes based on the JSON */
var nodes = partition.nodes({
children: json
});
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) { return "path-" + i; })
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("fill", colour)
.on("click", click);
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) {
return "path-" + i;
})
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("fill", colour)
.on("click", click);
var text = vis.selectAll("text").data(nodes);
var textEnter = text.enter().append("text")
.style("fill-opacity", 1)
.style("fill", function(d) {
return brightness(d3.rgb(colour(d))) < 125 ? "#eee" : "#000";
})
.attr("text-anchor", function(d) {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d) {
/** Get the text details and define the rotation and general position */
var multiline = (d.name || "").split(" ").length > 1,
var text = vis.selectAll("text").data(nodes);
var textEnter = text.enter().append("text")
.style("fill-opacity", 1)
.style("fill", function(d) {
return brightness(d3.rgb(colour(d))) < 125 ? "#eee" : "#000";
})
.attr("text-anchor", function(d) {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d) {
/** Get the text details and define the rotation and general position */
var multiline = (d.name || "").split(" ").length > 1,
angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
})
.on("click", click);
/** Managing text - alway maximum two words */
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) { return d.depth ? d.name.split(" ")[0] : ""; });
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) { return d.depth ? d.name.split(" ")[1] || "" : ""; });
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
})
.on("click", click);
/** Managing text - alway maximum two words */
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) {
return d.depth ? d.name.split(" ")[0] : "";
});
textEnter.append("tspan")
.attr("x", 0)
.attr("dy", "1em")
.text(function(d) {
return d.depth ? d.name.split(" ")[1] || "" : "";
});
});
});
function click(d) {
function click(d) {
path.transition()
.duration(duration)
.attrTween("d", arcTween(d));
.duration(duration)
.attrTween("d", arcTween(d));
// Somewhat of a hack as we rely on arcTween updating the scales.
text
.style("visibility", function(e) {
text.style("visibility", function(e) {
return isParentOf(d, e) ? null : d3.select(this).style("visibility");
})
.transition().duration(duration)
.attrTween("text-anchor", function(d) {
})
.transition().duration(duration)
.attrTween("text-anchor", function(d) {
return function() {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
};
})
.attrTween("transform", function(d) {
})
.attrTween("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1;
return function() {
var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
};
})
.style("fill-opacity", function(e) { return isParentOf(d, e) ? 1 : 1e-6; })
.each("end", function(e) {
})
.style("fill-opacity", function(e) {
return isParentOf(d, e) ? 1 : 1e-6;
})
.each("end", function(e) {
d3.select(this).style("visibility", isParentOf(d, e) ? null : "hidden");
});
}
});
});
}
/* Returns whether p is parent of c */
function isParentOf(p, c) {
if (p === c) return true;
if (p.children) {
return p.children.some(function(d) {
return isParentOf(d, c);
});
}
return false;
if (p === c) return true;
if (p.children) {
return p.children.some(function(d) {
return isParentOf(d, c);
});
}
return false;
}
/* Generated random colour */
function colour(d) {
if (d.children) {
// There is a maximum of two children!
var colours = d.children.map(colour),
if (d.children) {
// There is a maximum of two children!
var colours = d.children.map(colour),
a = d3.hsl(colours[0]),
b = d3.hsl(colours[1]);
// L*a*b* might be better here...
return d3.hsl((a.h + b.h) / 2, a.s * 1.2, a.l / 1.2);
}
return d.colour || "#fff";
// L*a*b* might be better here...
return d3.hsl((a.h + b.h) / 2, a.s * 1.2, a.l / 1.2);
}
return d.colour || "#fff";
}
/* Interpolate the scales! */
function arcTween(d) {
var my = maxY(d),
xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, my]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, r]);
return function(d) {
return function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
};
var my = maxY(d),
xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, my]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, r]);
return function(d) {
return function(t) {
x.domain(xd(t));
y.domain(yd(t)).range(yr(t));
return arc(d);
};
};
}
/* */
function maxY(d) {
return d.children ? Math.max.apply(Math, d.children.map(maxY)) : d.y + d.dy;
return d.children ? Math.max.apply(Math, d.children.map(maxY)) : d.y + d.dy;
}
/* Use a formula for contrasting colour
http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
*/
function brightness(rgb) {
return rgb.r * .299 + rgb.g * .587 + rgb.b * .114;
}
return rgb.r * .299 + rgb.g * .587 + rgb.b * .114;
}

@ -593,6 +593,7 @@ class Skill extends Model {
unset($skills);
return $skills_tree;
}
/**
* Get skills tree as a simplified JSON structure
*
@ -600,8 +601,10 @@ class Skill extends Model {
public function get_skills_tree_json($user_id = null, $return_flat_array = false) {
$tree = $this->get_skills_tree($user_id, $return_flat_array);
$simple_tree = array();
foreach ($tree['children'] as $element) {
$simple_tree[] = array('name' => $element['name'], 'children' => $this->get_skill_json($element['children']));
if (!empty($tree['children'])) {
foreach ($tree['children'] as $element) {
$simple_tree[] = array('name' => $element['name'], 'children' => $this->get_skill_json($element['children']));
}
}
//$s = array('\/');
//return str_replace($s,'/',json_encode($simple_tree[0]['children']));

@ -1,15 +1,15 @@
<div id="menu" class="well" style="top:20px; left:20px; width:380px; z-index: 9000; opacity: 0.9;">
<h3>{{'Skills'|get_lang}}</h3>
<h3>{{ 'Skills'|get_lang }}</h3>
<div class="btn-group">
<a style="z-index: 1000" class="btn" id="add_item_link" href="#">{{'AddSkill'|get_lang}}</a>
<a style="z-index: 1000" class="btn" id="return_to_root" href="#">{{'Root'|get_lang}}</a>
<a style="z-index: 1000" class="btn" id="return_to_admin" href="{{_p.web_main}}admin">{{'BackToAdmin'|get_lang}}</a>
<a style="z-index: 1000" class="btn" id="add_item_link" href="#">{{ 'AddSkill'|get_lang }}</a>
<a style="z-index: 1000" class="btn" id="return_to_root" href="#">{{ 'Root'|get_lang }}</a>
<a style="z-index: 1000" class="btn" id="return_to_admin" href="{{ _p.web_main }}admin">{{ 'BackToAdmin'|get_lang }}</a>
</div>
</div>
<div id="vis"><img src=""></div>
{{ html }}
<div id="vis">
<img src="">
</div>
<!--div id="dialog-form" style="display:none; z-index:9001;">
<p class="validateTips"></p>

Loading…
Cancel
Save