[Users] TreePanel with Vector Legend
Adam Ratcliffe
adam at prema.co.nz
Mon Aug 16 11:25:29 CEST 2010
Hi Andreas,
Thanks for the feedback. I did strike a few issues with the
TreeNodeUI not being an Ext.Component so your approach sounds like the
way to go. I'll get back in touch once I have something working.
Cheers
Adam
On Mon, Aug 16, 2010 at 8:09 PM, Andreas Hocevar <ahocevar at opengeo.org> wrote:
> Hi,
>
> although your progress here is impressive, I think it would have been simpler to add the VectorLegend as a component, after creating a generic tree node that can render an Ext.Component (which the VectorLegend is). This is covered by http://trac.geoext.org/ticket/139, and there is a working patch already. My objection to this patch was that extending nodes with different mixins can become complicated, so I proposed http://trac.geoext.org/ticket/185, which also has a working patch, plus patches from others that show how node additions can be created easily based on my patch.
>
> If you want to try this approach, I'll gladly assist.
>
> Regards,
> Andreas.
>
> On Aug 16, 2010, at 01:44 , Adam Ratcliffe wrote:
>
>> Hi Andreas,
>>
>> I had sometime over the weekend to start looking into how to implement
>> this. Below is my initial attempt, which while working, I'm not
>> completely happy with. Maybe you or somebody on the else on the list
>> can suggest some improvements?
>>
>> Some of the issues that I had were:
>>
>> - My class duplicates code from GeoExt.VectorLegend
>>
>> - I needed to override GeoExt.FeatureRenderer.onRender() so that the
>> wrapper element that's created for the legend swatch is an inline
>> element rather than a block-level element. It would be helpful if
>> GeoExt.FeatureRenderer allowed the element type to be specified via
>> the 'autoEl' config option like other ExtJS components.
>>
>> - I had issues with vertical alignment of the legend swatch relative
>> to the node checkbox and label text. I was able to align these
>> elements satisfactorily under FF and Safari using the styles below - I
>> haven't tested in IE yet.
>>
>> Styles
>> ----------
>>
>> .x-tree-node-legend {
>> height: 18px;
>> }
>>
>> .x-tree-node-legend input {
>> margin-left: 2px !important;
>> vertical-align: top !important;
>> }
>>
>> .x-tree-node-legend .x-tree-node-anchor span {
>> vertical-align: top !important;
>> }
>>
>> Script
>> ---------
>>
>> GeoExt.tree.VectorLayerNodeUI = Ext.extend(GeoExt.tree.LayerNodeUI, {
>>
>> constructor: function(config) {
>> GeoExt.tree.VectorLayerNodeUI.superclass.constructor.apply(this,
>> arguments);
>>
>> if (!this.symbolType) {
>> if (this.feature) {
>> this.symbolType = this.symbolTypeFromFeature(this.feature);
>> } else if (this.node.layer) {
>> if (this.node.layer.geometryType) {
>> this.symbolType =
>> this.symbolTypeFromGeometry(this.node.layer.geometryType);
>> } else if (this.node.layer.features.length > 0) {
>> var feature = this.node.layer.features[0].clone();
>> feature.attributes = {};
>> this.feature = feature;
>> this.symbolType = this.symbolTypeFromFeature(this.feature);
>> } else {
>> this.node.layer.events.on({
>> featuresadded: this.onFeaturesAdded,
>> scope: this
>> });
>> }
>> }
>> }
>>
>> this.setRules();
>> },
>>
>> symbolTypeFromGeometry: function(geometry) {
>> var symbolType = geometry.prototype.CLASS_NAME.split('.').pop();
>> return (symbolType == 'LineString') ? 'Line' : symbolType;
>> },
>>
>> symbolTypeFromFeature: function(feature) {
>> var match = feature.geometry.CLASS_NAME.match(/Point|Line|Polygon/);
>> return (match && match[0]) || "Point";
>> },
>>
>> onFeaturesAdded: function() {
>> this.node.layer.events.un({
>> featuresadded: this.onFeaturesAdded,
>> scope: this
>> });
>> var feature = this.node.layer.features[0].clone();
>> feature.attributes = {};
>> this.feature = feature;
>> this.symbolType = this.symbolTypeFromFeature(this.feature);
>> if (!this.rules) {
>> this.setRules();
>> }
>> this.update();
>> },
>>
>> update: function() {
>> if (this.symbolType && this.rules) {
>> this.createRuleRenderer(this.rules[0],
>> this.legendWrap).render(this.elNode, 2);
>> }
>> },
>>
>> setRules: function() {
>> var style = this.node.layer.styleMap &&
>> this.node.layer.styleMap.styles["default"];
>> if (!style) {
>> style = new OpenLayers.Style();
>> }
>> if (style.rules.length === 0) {
>> this.rules = [
>> new OpenLayers.Rule({
>> symbolizer: style.createSymbolizer(this.feature)
>> })
>> ];
>> } else {
>> this.rules = style.rules;
>> }
>> },
>>
>> createRuleRenderer: function(rule) {
>> var symbolizer = rule.symbolizer;
>> if (symbolizer[this.symbolType]) {
>> symbolizer = symbolizer[this.symbolType];
>> }
>> return new GeoExt.FeatureRenderer({
>> resolution: 1,
>> width: 18,
>> height: 18,
>> symbolType: this.symbolType,
>> symbolizers: [symbolizer],
>> // override onRender() so that the vector element can
>> // be wrapped with an inline element in place of a block element
>> onRender: function(ct, position) {
>> if(!this.el) {
>> this.el = document.createElement('span');
>> this.el.className = 'legend-wrap';
>> this.el.id = this.getId();
>> }
>> if(!this.renderer || !this.renderer.supported()) {
>> this.assignRenderer();
>> }
>> this.renderer.map = {
>> getResolution: (function() {
>> return this.resolution;
>> }).createDelegate(this)
>> };
>> this.drawFeature();
>> GeoExt.FeatureRenderer.superclass.onRender.apply(this,
>> arguments);
>> }
>> });
>> },
>>
>> renderElements : function(n, a, targetNode, bulkRender){
>> // add some indent caching, this helps performance when
>> rendering a large tree
>> this.indentMarkup = n.parentNode ?
>> n.parentNode.ui.getChildIndent() : '';
>>
>> var cb = Ext.isBoolean(a.checked),
>> nel,
>> href = a.href ? a.href : Ext.isGecko ? "" : "#",
>> buf = ['<li class="x-tree-node"><div
>> ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf
>> x-tree-node-legend x-unselectable ', a.cls,'" unselectable="on">',
>> '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
>> '<img src="', this.emptyIcon, '" class="x-tree-ec-icon
>> x-tree-elbow" />',
>> cb ? ('<input class="x-tree-node-cb" type="checkbox" ' +
>> (a.checked ? 'checked="checked" />' : '/>')) : '',
>> '<a hidefocus="on" class="x-tree-node-anchor"
>> href="',href,'" tabIndex="1" ',
>> a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span
>> unselectable="on">',n.text,"</span></a></div>",
>> '<ul class="x-tree-node-ct" style="display:none;"></ul>',
>> "</li>"].join('');
>>
>> if(bulkRender !== true && n.nextSibling && (nel =
>> n.nextSibling.ui.getEl())){
>> this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
>> }else{
>> this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
>> }
>>
>> this.elNode = this.wrap.childNodes[0];
>> this.ctNode = this.wrap.childNodes[1];
>> var cs = this.elNode.childNodes;
>> this.indentNode = cs[0];
>> this.ecNode = cs[1];
>> var index = 2;
>> if(cb){
>> this.checkbox = cs[2];
>> // fix for IE6
>> this.checkbox.defaultChecked = this.checkbox.checked;
>> index++;
>> }
>> this.anchor = cs[index];
>> this.textNode = cs[index].firstChild;
>>
>> if(this.symbolType) {
>> this.createRuleRenderer(this.rules[0]).render(this.elNode, 2);
>> }
>> }
>> });
>>
>> Cheers
>> Adam
>>
>> Cheers
>> Adam
>>
>> On Mon, Aug 2, 2010 at 7:44 PM, Andreas Hocevar <ahocevar at opengeo.org> wrote:
>>> Oops, sorry. I had missed the "TreePanel" part of your original mail (thought you wanted a VectorLegend in your LegendPanel). At this point, you cannot render a legend with a tree node. There are several tickets with patches already, which may help you:
>>>
>>> http://trac.geoext.org/ticket/185
>>> http://trac.geoext.org/ticket/139
>>>
>>> Regards,
>>> Andreas.
>>>
>>> On Aug 2, 2010, at 09:27 , Adam Ratcliffe wrote:
>>>
>>>> That's great.
>>>>
>>>> Just one question, how do I configure my TreePanel to create the node
>>>> with a vector legend instead of an icon, my current tree configuration
>>>> looks like this:
>>>>
>>>> var config = {
>>>> autoScroll: true,
>>>> animate: true,
>>>> border: false,
>>>> region: 'center',
>>>> stateful: true,
>>>> root: new GeoExt.tree.LayerContainer({
>>>> text: 'Layers',
>>>> loader: new GeoExt.tree.LayerLoader({
>>>> store: this.layerStore,
>>>> createNode: function(attr) {
>>>> var layer = attr.layer;
>>>> attr.iconCls = layer.gsGeometryType ? 'icon_'
>>>> + layer.gsGeometryType.toLowerCase() : 'icon_point';
>>>> return
>>>> GeoExt.tree.LayerLoader.prototype.createNode.call(this, attr);
>>>> }
>>>> }),
>>>> layerStore: this.layerStore,
>>>> leaf: false,
>>>> expanded: true
>>>> })
>>>> }
>>>>
>>>> Cheers
>>>> Adam
>>>>
>>>> On Mon, Aug 2, 2010 at 6:13 PM, Andreas Hocevar <ahocevar at opengeo.org> wrote:
>>>>> Hi,
>>>>>
>>>>> On Aug 2, 2010, at 05:41 , Adam Ratcliffe wrote:
>>>>>
>>>>>> I'd like to dynamically render symbols based upon the layer geometry
>>>>>> type and styles in a TreePanel similar to the vector legend example
>>>>>> here: http://dev.geoext.org/trunk/geoext/examples/vector-legend.html
>>>>>>
>>>>>> Is this possible?
>>>>>
>>>>> Yes! Just configure your vector layer with a StyleMap. The VectorLegend will be built from the style and rules of the "default" render intent.
>>>>>
>>>>> Regards,
>>>>> Andreas.
>>>>>
>>>>>>
>>>>>> Cheers
>>>>>> Adam
>>>>>> _______________________________________________
>>>>>> Users mailing list
>>>>>> Users at geoext.org
>>>>>> http://www.geoext.org/cgi-bin/mailman/listinfo/users
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Andreas Hocevar
>>>>> OpenGeo - http://opengeo.org/
>>>>> Expert service straight from the developers.
>>>>>
>>>>>
>>>
>>> --
>>> Andreas Hocevar
>>> OpenGeo - http://opengeo.org/
>>> Expert service straight from the developers.
>>>
>>>
>> _______________________________________________
>> Users mailing list
>> Users at geoext.org
>> http://www.geoext.org/cgi-bin/mailman/listinfo/users
>
> --
> Andreas Hocevar
> OpenGeo - http://opengeo.org/
> Expert service straight from the developers.
>
>
More information about the Users
mailing list