Generating onclick text at the bottom of my SVG, modifying 'selected' colour - javascript

With the aid of a tutorial, I've built a map of five regions of England in SVG. I've used Raphael to work with it a little. Most of it seems to be turning out alright so far:
http://codepen.io/msummers40/pen/EjExeO
I'm trying to add two more features and am just not sure how to do it. Are you able to help, please?
I'd like to: Set up the effect of the regions turning red upon clicking so that only the most recently clicked region is coloured. Can you help explain what I'm supposed to do to make this shift from region to region? At the moment, a region gets clicked and stays highlighted.
I'd like to figure out how to add more text to the bottom of the canvas. It may mean adding more information to my JSON but I'm hoping that I can add the text - about two paragraphs with a hyperlink - as a string.
Can you please let me know if you have thoughts about ways that I can do the two things outlined above?
Thank you,
Matt
The full code is on Codepen. What I've added below is a representative sample of the code.
var regions = [
{'title':"northeast_england", 'path' : "M219.02,6.876l-0.079,0.05l-0.482,0.371L218.23,7.47l-0.858,0.346h-0.008l-0.307,0.26l-0.779,0.666 l-0.104,0.278l-0.005,0.019l0.056,0.481l0.116,0.846l0.048,0.395l-0.344,1.05l-0.052-0.007v0.007l-0.635-0.081l-0.375,0.167 l-0.148,0.061v0.006l-0.1,0.328l0.178,0.338l-0.104,0.353h-0.006l-0.32,0.179l-0.056,0.031l-0.161,0.729h-0.006v0.012l-0.271,0.117 l-0.08,0.031l-0.031-0.019l-0.043,0.019l-0.327-0.167l-0.147-0.079l-0.117-0.007h-0.021l-0.216-0.006l-0.419,0.252l-0.009,0.007 l-0.004,0.302v0.605l-0.117,0.292l-0.037,0.11h-0.006v0.006h-0.025l-0.37,0.056l-0.536,0.079l-0.562,0.372l0.017,0.165l0.033,0.187 l0.481,0.788l0.023,0.038l0.008,0.013l-0.988,0.425l-0.594,0.637l-0.011,0.03l-0.187,0.637l-0.068,0.062l-0.801,0.747l-0.409,0.617 l0.062,0.414l0.068,0.414l-0.012,0.012l-0.203,0.228h-0.008l-0.123,0.05l-0.006,0.005l-0.377,0.136l-0.073,0.074l-0.13,0.143 l-0.401,0.426l-0.081,0.08l-0.055,0.055l-0.116,0.136l-0.05,0.364l0.646,0.191l0.025,0.119l0.05,0.153l-0.265,0.148l-0.26,0.155 l-0.155-0.006l-0.005,0.006l-0.309-0.006l-0.648-0.365l-0.624,0.142l-0.363,0.087l-......LOTS MORE COORDINATES...."},
THERE ARE SEVERAL OTHER SVG REGIONS/SHAPES IN THE CODEPEN LINK
var MAP_WIDTH = 600;
var MAP_HEIGHT = 600;
var mapContainer = document.getElementById("map");
var map = new Raphael(mapContainer, MAP_WIDTH, MAP_HEIGHT);
var group = map.set();
var style = {
fill: "#ddd",
stroke: "#aaa",
"stroke-width": 1,
"stroke-linejoin": "round",
cursor: "pointer"
};
regions.forEach(function(region){
group.push(
map.path(region.path).attr('title', region.title)
);
});
group.attr(style);
group.click(function(){
var slug = this.attr('title');
var title;
var fill = this.attr('fill') == 'red' ? '#1f1f1f' : 'red';
// format the title
title = slug.split('-')
.map(function(subString){
return subString[0].toUpperCase() + subString.substr(1);
})
.join(' ')
.trim();
// add some color
this.attr('fill', fill);
// do something useful
document.getElementById('title').textContent = title;
});

For the highlight thing, what I would do is have your click function as follows (pseudocode)::
on-region-clicked {
remove class "highlight" from all regions
add class "highlight" to clicked region
}
Where class "highlight" is:
.highlight {
fill: red;
}
I'll leave the actual Raphael code up to you.

Related

Data label not rendered on sapui5 viz dual y-axis graph when line and column intersect

I have a requirement to show data labels of two graphs on the same axes.
Only when they intersect, one of the two labels won't show. This can be demonstrated below:
As you can see on the 2nd, 5th and 6th columns from the left with values 0%, 7% and 8% respectively
only the orange line values are shown but the blue column values are missing.
This is the final html of the graph after rendering:
So data-datapoint-id 142, 145 and 146 are missing from the html.
I tried using the plotArea.dataLabel.renderer function as a manipulation of what was proposed here but nothing changed, still not rendering.
Anyone encountered a similar problem? Is that a sapui5 issue or can it be fixed by manually inserting the labels into the HTML if so how?
Thanks,
Ori
Using SVG text and jQuery I managed to manually insert the labels into the top middle of the blue rectangle columns.
This is the result, not perfect but works:
and this is the code:
chart.setVizProperties({
plotArea: {
dataLabel: {
formatString: {'פחת כללי': FIORI_PERCENTAGE_FORMAT_2},
renderer: function (oLabel) {
// Create empty text node to be returned by the function such that the label won't be rendered automatically
var node = document.createElement("text");
if (oLabel.ctx.measureNames === "כמות פחת כללי") {
var kamutLabelIdx = oLabel.ctx._context_row_number;
// Use jQuery and SVG to manipulate the HTML
var kamutLabelQuery = '[data-id=\"' + kamutLabelIdx + '\"]';
var kamutColumn = $(kamutLabelQuery)[0];
// Create text element as child of the column
kamutColumn.innerHTML += "<text>" + oLabel.text + "</text>";
var labelNode = $(kamutLabelQuery += ' text');
// Set the label position to be at the middle of the column
const labelLength = 60;
const xPos = (labelLength + oLabel.dataPointWidth) / 2;
const yPos = oLabel.styles['font-size'];
labelNode.attr({
"textLength" : labelLength,
"x" : xPos,
"y" : yPos,
"font-size" : yPos
});
return node;
}
}
}
}
});
The oLabel parameter of the renderer function provides useful info about the data label to be created:
I still wonder if that's a bug with sapui5 vizframe and if there is a simpler way to do this.
Please let me know of your thoughts

Hover color on Kendo UI Bar Chart bars

I am trying to find a way to completely change the color of a Kendo UI Bar Chart bar when it is hovered over. I do know that there is the series.highlight.color config option, but this seems to add only a tint in that color. I am wanting to completely replace the normal bar color with a different hover color. I have been pouring through the docs but can't seem to find a configuration option to do this even though it seems like there has to be a way to do this through Kendo config options without having to resort to hacking it.
Any help is much appreciated!
You can use the series.highlight.visual property to draw the bar with a solid color:
$("#chart").kendoChart({
series: [{
type: "bar",
data: [1, 2],
highlight: {
visual: function(e) {
var origin = e.rect.origin;
var bottomRight = e.rect.bottomRight();
var topRight = e.rect.topRight();
var topLeft = e.rect.topLeft();
var c = "green";
var bc = "#555";
var path = new kendo.drawing.Path({
fill: {color: c,opacity: 1,},
stroke: {color: bc,opacity: 0.7,width: 2,}
})
.moveTo(origin.x, bottomRight.y)
.lineTo(bottomRight.x, bottomRight.y)
.lineTo(topRight.x, topRight.y)
.lineTo(topLeft.x, topLeft.y)
.close();
return path;
}
}
}]
});
DEMO
Within the visual function you can get at the item and base the color on value or another field, etc.

How to append an element inside another on snapsvg?

I'm building a domino piece using Snapsvg http://snapsvg.io/
Here is the code so far.
var s = Snap(800,600);
// elem structure
var elem = s.rect(10,10,100,200);
var s1 = s.rect(0,0,90,90);
elem.attr({
fill: '#fff',
stroke: '#000',
strokeWidth: 2
});
s1.attr({
fill: '#bada55'
});
s1.append(elem)
I built the piece structure var elem that is width:100 and height:200 and I built an square var s1 width:90 height:90. I'm trying to append s1 inside elem. When i use s1.append(elem), the elem disappears, what am I doing wrong?
In SVG graphical elements i.e. rect, polygon etc are not nestable.
There are containers (Paper.group) which can contain graphical elements which you can add transforms to to move multiple elements at once if you want. You could create one of those and put both your rect elements within it as siblings.

Putting HTML code on JointJS link

I have worked with JointJS now for a while, managing to create elements with HTML in them.
However, I am stuck with another problem, is it possible to place HTML code, like
href, img etc, on a JointJS link and how do I do this?
For example, if I have this link, how do I modify it to contain HTML:
var link = new joint.dia.Link({
source: { id: sourceId },
target: { id: targetId },
attrs: {
'.connection': { 'stroke-width': 3, stroke: '#000000' }
}
});
Thank you!
JointJS doesn't have a direct support for HTML in links. However, it is possible to do with a little bit of JointJS trickery:
// Update position of our HTML whenever source/target or vertices of our link change:
link.on('change:source change:target change:vertices', function() { updateHTMLPosition(link, $html) });
// Update position of our HTML whenever a position of an element in the graph changes:
graph.on('change:position', function() { updateHTMLPosition(link, $html) });
var $html = $('<ul><li>one</li><li>two</li></ul>');
$html.css({ position: 'absolute' }).appendTo(paper.el);
// Function for updating position of our HTML list.
function updateHTMLPosition(link, $html) {
var linkView = paper.findViewByModel(link);
var connectionEl = linkView.$('.connection')[0];
var connectionLength = connectionEl.getTotalLength();
// Position our HTML to the middle of the link.
var position = connectionEl.getPointAtLength(connectionLength/2);
$html.css({ left: position.x, top: position.y });
}
Bit of an old question, but thought I'd add some more ideas. You can add extra svg markup to the label in a link if you like by extending the link object and then setting attributes where needed. For example:
joint.shapes.custom.Link = joint.dia.Link.extend({
labelMarkup: '<g class="label"><rect /><text /></g>'
});
This code overrides the markup for the label, so you can add extra elements in there. You can also update attributes on these elements by:
link.attr('text/text', "new text");
However hyperlinks won't work (at least I haven't got them working in Chrome) and I believe this is because Jointjs listens for all events in the model. So what you should do is use inbuilt events in Jointjs to listen for connection clicks:
paper.on('cell:pointerclick', function(cellView, evt, x, y){
console.log(cellView);
});

In raphaeljs, is there a way to place text within an object to keep rollover state

In creating a svg map using raphael js where I have hover states. How ever I am trying to write the country names onto the map. The problem I am facing is the names become their own object and block the country so I loose hover and click when the cursor is directly over the text. Is there a way where I can draw the text and not have it block the map. I've tried set() but with no sucess.
Thanks,
What I have below doesn't have the text() or print() included:
var r = Raphael('map', 1450, 2180);
arr = new Array();
for (var country in paths) {
var obj = r.path(paths[country].path);
countryName = paths[country].name;
color = paths[country].color;
scolor = paths[country].stroke;
obj.attr({fill:color,stroke:scolor,
'stroke-width': 1,
'stroke-linejoin': 'round'});
arr[obj.id] = country;
obj
.hover(function(){
console.log(arr[this.id]);
this.animate({
fill: paths[arr[this.id]].hover
}, 300);
}, function(){
this.animate({
fill: paths[arr[this.id]].color
}, 300);
})
});
Try setting the pointer-events attribute to none for the text elements.
Documentation:
http://www.w3.org/TR/SVG/interact.html#PointerEventsProperty

Categories