Setting color to a string using javascript - javascript

I am building a dynamic array and have the following code, i am trying to add a color to the "name" of the array. Everything else works perfectly apart from "fontcolor("red")" .
if (val < 0) {
myArray.push({
"name" : myVariable.fontcolor("red"),
"size" : -10
});
} else {
myArray.push({
"name" : myVariable,
"size" : 5
});
}
I end up with the following when displayed on thet HTML page:
<font color="red">Strong rubber(minus)</font>
I am actualy drawing a chart and I am using the d3.js to draw the charts, my code that draws up "Dog Toys". myVariable has the value "myVariable"
<g style="cursor: pointer; opacity: 1; " transform="translate(0,0)">
<text x="-6" y="10" dy=".50em" text-anchor="end">Dog Toys</text>
<rect width="478.57142857142867" height="20" style="fill: #4682b4; "></rect>
</g>
Any idea how i could set a color to text, when its displayed on the web page?

Try
myVariable.style.color = "Red"

myVariable.style.color = "red";

Related

Add text to SVG path dynamically

I have an SVG exported from Adobe Illustrator with several paths like this, which produces a small polygon I intend to use as a text box
<svg viewbox="387 390 74 20">
<g>
<path class="st37" d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0 C460,404.42,456.42,408,452,408z" />
</g>
</svg>
I'd like to dynamically add text to it. I've seen many similar questions here, but most of them involed specifying a x and y property for a text element based on the x and y property the path element. My path, however, does not have such properties.
I've tried to use a textPath element with xlink:href pointing to my path. I gets attached to the path, but the text wraps my path element instead of being inside it.
So, is there a way to achieve this? I'm open to different solutions here. My dream would be to use javascript to get the path element and add the text from there. But I could also edit the base SVG file to add a text or any other relevant element and attributes to make this work, as long as I can change the text dynamically from javascript later. And since this SVG is produced by Illustrator, I could also try different export options there in order to get a proper output for my goal.
Here's some sample code that takes a label path and adds a <text> element after it with whatever text you choose.
let label1 = document.querySelector("#label1");
addLabelText(label1, "Something");
function addLabelText(bgPath, labelText)
{
let bbox = bgPath.getBBox();
let x = bbox.x + bbox.width / 2;
let y = bbox.y + bbox.height / 2;
// Create a <text> element
let textElem = document.createElementNS(bgPath.namespaceURI, "text");
textElem.setAttribute("x", x);
textElem.setAttribute("y", y);
// Centre text horizontally at x,y
textElem.setAttribute("text-anchor", "middle");
// Give it a class that will determine the text size, colour, etc
textElem.classList.add("label-text");
// Set the text
textElem.textContent = labelText;
// Add this text element directly after the label background path
bgPath.after(textElem);
}
.st37 {
fill: linen;
}
.label-text {
font-size: 10px;
fill: rebeccapurple;
transform: translate(0, 3px); /* adjust vertical position to centre text */
}
<svg viewbox="387 390 74 20">
<g>
<path id="label1" class="st37" d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0 C460,404.42,456.42,408,452,408z" />
</g>
</svg>
Since you can edit your base SVG align
create a proper SVG to work with
Your path is a background label starting (red circle) at a large offset x=452 y=408
I would recreate it,
starting at the green circle, (editor: https://yqnn.github.io/svg-path-editor/)
in a viewBox="0 0 80 20"
To get single coordinates for both backgroundlabel and (blue) textPath line
after that use JavaScript to add text dynamically.
No need for text x,y calculations, pathLength and startoffset do the work
Or if you go fancy you can create the blue line dynamically from getBBox()
That will also work with your current path; just more calculations required
It is all about coordinates,
and positioning the blue line (with stroke="transparent" then):
playground:
<svg viewbox="387 390 74 20">
<path fill="lightgreen" d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0C460,404.42,456.42,408,452,408z" />
<circle cx="452" cy="408" r="2" fill="red"/>
<circle cx="388" cy="400" r="2" fill="green"/>
<path id="P" pathLength="100" d="M388 400h72" stroke="blue"/>
<text>
<textPath href="#P" startoffset="50" text-anchor="middle" dominant-baseline="middle"
fill="green" font-size="14px">My Text</textPath>
</text>
</svg>
Thanks for the answers! I end up using a tweaked version of Paul LeBeau's function to take into account the structure suggested by Danny '365CSI' Engelman so I don't have to use translate to center the text vertically.
let label = document.querySelector("#mylabel");
addLabelTextPath(label, "Something");
function addLabelTextPath(bgPath, labelText) {
let bbox = bgPath.getBBox();
let x = bbox.x + bbox.width / 2;
let y = bbox.y + bbox.height / 2;
// Create the path line
let pathElem = document.createElementNS(bgPath.namespaceURI, "path");
pathElem.setAttribute("pathLength", 100);
pathElem.setAttribute("d", `M${bbox.x} ${y}h${bbox.width}`);
pathElem.id = `baseline-${bgPath.id}`;
// Create a <text> element
let textElem = document.createElementNS(bgPath.namespaceURI, "text");
// Create a <textPath> element
let textPath = document.createElementNS(bgPath.namespaceURI, "textPath");
textPath.setAttribute("href", `#${pathElem.id}`);
//Center text
textPath.setAttribute("dominant-baseline", "Middle");
textPath.setAttribute("startOffset", 50);
textPath.setAttribute("text-anchor", "middle");
// Give it a class that will determine the text size, colour, etc
textPath.classList.add("label-text");
// Set the text
textPath.textContent = labelText;
// Add the elements directly after the label background path
bgPath.after(pathElem);
pathElem.after(textElem);
textElem.appendChild(textPath);
}
.st37 {
fill: lightblue;
}
.label-text {
font-size: 10px;
fill: darkblue;
}
<svg viewbox="387 390 74 20">
<g>
<path id="mylabel" class="st37" d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0 C460,404.42,456.42,408,452,408z" />
</g>
</svg>

SVG.js TextPath not aligned with path (Verticaly)

I'm trying to place a text onto a path with svg.js
Here is my fiddle:
https://jsfiddle.net/Byteschmiede/ytz67egn/1/
var draw = SVG().addTo('body').size(500, 500)
draw.svg(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100%" height="100%" viewBox="0 0 4725 2363" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path id="text1326" d="M2362.2,952.109C2548.36,773.615 2727.44,622.128 2899.46,497.647C3071.47,370.823 3216.39,286.272 3334.21,243.993C3452.02,201.721 3580.45,180.583 3719.47,180.58C4011.66,180.583 4247.3,278.051 4426.39,472.986C4607.82,665.577 4698.54,899.267 4698.55,1174.06C4698.54,1361.95 4658.48,1535.75 4578.37,1695.46C4498.25,1855.16 4383.97,1976.12 4235.52,2058.32C4089.42,2140.53 3920.94,2181.63 3730.08,2181.62C3482.66,2181.63 3265.87,2128.78 3079.72,2023.09C2895.92,1917.4 2656.75,1717.77 2362.2,1424.19C2055.87,1727.16 1811.99,1929.15 1630.55,2030.14C1449.11,2131.13 1238.21,2181.63 997.866,2181.62C691.537,2181.63 452.365,2086.51 280.351,1896.27C110.692,1706.03 25.862,1465.29 25.863,1174.06C25.862,901.616 115.404,667.926 294.489,472.986C475.929,278.051 712.744,180.583 1004.94,180.58C1146.32,180.583 1275.92,201.721 1393.74,243.993C1511.55,286.272 1655.29,370.823 1824.95,497.647C1996.97,622.128 2176.05,773.615 2362.2,952.109M2591.95,1170.53C2841.72,1417.14 3046.73,1585.07 3206.96,1674.32C3369.55,1761.22 3530.96,1804.67 3691.2,1804.67C3891.49,1804.67 4048.18,1745.95 4161.29,1628.52C4274.4,1508.74 4330.95,1364.3 4330.95,1195.19C4330.95,1009.65 4274.4,856.992 4161.29,737.208C4050.54,615.082 3903.27,554.017 3719.47,554.014C3615.79,554.017 3515.64,572.806 3419.04,610.382C3322.42,645.614 3206.96,709.027 3072.65,800.622C2938.33,889.873 2778.1,1013.18 2591.95,1170.53M2132.46,1170.53C1962.8,1027.27 1810.81,909.836 1676.5,818.237C1542.19,724.294 1424.37,657.357 1323.05,617.428C1221.72,577.503 1110.97,557.54 990.797,557.537C818.78,557.54 676.22,617.43 563.115,737.208C450.009,856.992 393.456,1009.65 393.457,1195.19C393.456,1324.37 422.911,1433.58 481.82,1522.83C540.729,1612.08 612.598,1681.37 697.428,1730.68C784.613,1780.01 893.006,1804.67 1022.61,1804.67C1192.27,1804.67 1357.21,1760.05 1517.45,1670.8C1677.68,1581.55 1882.68,1414.79 2132.46,1170.53" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
<path id="textCurve3" d="M294.489,472.986C475.929,278.051 712.744,180.583 1004.94,180.58C1146.32,180.583 1275.92,201.721 1393.74,243.993C1511.55,286.272 1655.29,370.823 1824.95,497.647" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
<path id="textCurve2" d="M2899.46,497.647C3071.47,370.823 3216.39,286.272 3334.21,243.993C3452.02,201.721 3580.45,180.583 3719.47,180.58C4011.66,180.583 4247.3,278.051 4426.39,472.986" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
<path id="textCurve1" d="M564.216,1310.73C609.732,1475.4 770.154,1619.22 909.116,1635.49C993.881,1645.42 1152.78,1644.6 1262.96,1605.82C1479.72,1529.53 1626.78,1408.31 1802.89,1258.49" style="fill:none;fill-rule:nonzero;stroke:rgb(177,0,52);stroke-width:1px;"/>
</svg>
`)
let textCurve1 = draw.find("#textCurve1")[0]
let textPath = textCurve1.text("Forever").font({
size: textCurve1.height()
})
.attr({
startOffset: '50%',
'text-anchor': 'middle'
})
.fill({
opacity: 0
}).stroke({
color: "#000",
width: 1
})
The red line is the target path.
The Text needs to follow the path.
As you can see, the text curve is correct but the placement is way to low on the y axis.
I'm not sure how to solve this, since there aren't much opportunities.
I tried attributes like dominant-baseline and baseline-alignment but nothing workend
Here is a picture of the svg
You can use a tspan with a dx attribute to move specific text up or down.
const text = draw.text((text) => {
text.tspan('Some Text').dx(10)
}).path(textCurve1)

How to add a second tooltip to highcharts

I would like to add an external popover to highcharts. I'm currently looking at using WebUI Popover
So the standard highcharts popover displays the standard data, however, I would like to use WebUI Popover to display some data to explain a specific column, which can be fetched from the DB.
The actual fetching of data etc is fine, but I can't figure out how to display a specific popover for a column
The way WebUI Popover works is that it requires some HTML identifier to know where to show the popover:
$(#identifier).webuiPopover({"content"})
I cant find any identifier to use to link the popover to each column:
<g class="highcharts-series highcharts-tracker" visibility="visible" zIndex="0.1" transform="translate(55,48) scale(1 1)" style="" clip-path="url(#highcharts-3)">
<rect x="63.5" y="33.5" width="119" height="162" stroke="#FFFFFF" fill="rgb(124, 181, 236)" rx="0" ry="0" stroke-width="1" data-target="webuiPopover0"></rect>
<rect x="309.5" y="98.5" width="119" height="97" stroke="#FFFFFF" fill="rgb(124, 181, 236)" rx="0" ry="0" stroke-width="1"></rect>
<rect x="555.5" y="65.5" width="119" height="130" stroke="#FFFFFF" fill="rgb(124, 181, 236)" rx="0" ry="0" stroke-width="1"></rect>
</g>
So I want to show a popover for each coloumn (rect), but I really don't know how. I've tried:
var thePoint = "rect[x='" + 63.5 + "'][y='" + 33.5 + "']";
$(thePoint).webuiPopover(...)
This works to some extent, but obviously I've hard coded the 63,5 and 33,5. I've tried everything to dynamically get the x and y values, but I can never get those exact numbers.
Any other suggestions? Maybe if someone could explain how the built in popover gets the position?
There is this demo of clickable points: http://www.highcharts.com/demo/line-ajax
It uses Highslide.
If you want to use WebUI Popover, then you can find columns' rectangles and add popups. Example: http://jsfiddle.net/j57me5w1/
Looks like popups will start from top left corner.
$(function () {
$('#container').highcharts({
series: [{
type: 'column',
data: [1, 2, 3, 4, 5, 6, 7]
}]
});
var columns = $('.highcharts-tracker > rect');
$.each(columns, function (i, c) {
$(c).webuiPopover({
title: 'test',
content: '<div id="popup">popup content</div>',
closeable: true,
arrow: true,
placement: 'auto'
});
});
});

Highlighting an area of an image map based on search text

This is a new question feeding from another question that was just answered here.
I am working to highlight a <div> based on search text. We've accomplished that, thanks to Alex.
Now, I'm trying to apply the same concept to mapped coordinates on an image map.
There's a jsfiddle here.
Here's the JS(jQuery 1.10.2)...
function doSearch(text) {
$('#content div').removeClass('highlight');
$('#content div:contains(' + text + ')').addClass('highlight');
}
If you want a method without SVG, you can use the Maphilight jQuery plugin (GitHub).
I have updated your jsFiddle.
function doSearch(text) {
$('#content div').removeClass('highlight');
$('#content div:contains(' + text + ')').addClass('highlight');
$('#Map area').mouseout();
$('#Map area[data-text*="' + text + '"]').mouseover();
}
$(function() {
$('#imgmap').maphilight({ stroke: false, fillColor: "ffff00", fillOpacity: 0.6 });
});
Note: For a better result just use a bigger image, because your bunny.jpg is too small and you have forced its size with height/width attributes.
It is not possible with image-maps and area elements, because those are non visible elements, that cannot have child elements, nor styles. You would have to do it a lot more complicated like described here
But it is possible using modern embeded SVGs - Almost every browser does support it nowadays. Even IE.
I tested it with Chromium and Firefox.
It cannot be done with the help of jQuery as far as I know but with usual Javascript. The key is:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="663px" height="663px">
<image xlink:href="http://webfro.gs/south/kb2/images/bunny.jpg" x="0" y="0" width="663" height="663" />
<circle class="office" cx="504" cy="124" r="94" />
<circle class="fire-exit" cx="168" cy="150" r="97" />
<circle class="main-exit" cx="378" cy="589" r="48" />
</svg>
_
var svgns="http://www.w3.org/2000/svg";
var areas = document.getElementsByTagNameNS(svgns, 'circle');
$(areas).each(function(elem) {
if(areas[elem].className.baseVal === text) {
areas[elem].className.baseVal += ' highlightsvg';
} else {
areas[elem].className.baseVal = areas[elem].className.baseVal.replace(' highlightsvg', '');
}
});
See here in the JSFiddle. Is that the way you want it?

Raphael JS Pie: Add ID to path slices

I've seen this question asked over at the Raphael Google Groups, but after hours of searching there, and also on here, and Google, I cannot seem to find a solution.
I would simply like to be able to target my pie chart (svg path) slices using jQuery, but I cannot figure out how to add custom id's to the path tags - there is no ID attribute in there by default:
<path fill="#764c29" stroke="none" d="M350,350L350.6911881148345,94.00093308961084A256,256,0,0,1,561.8463375189659,206.2741175716762Z" style="stroke-width: 1; stroke-linejoin: round;" stroke-width="1" stroke-linejoin="round"/>
What would be ideal would be this:
<path **id="my_id"** fill="#764c29" stroke="none" d="M350,350L350.6911881148345,94.00093308961084A256,256,0,0,1,561.8463375189659,206.2741175716762Z" style="stroke-width: 1; stroke-linejoin: round;" stroke-width="1" stroke-linejoin="round"/>
Has anyone got an idea how this could be achieved?
This is the code I'm using to create the pie chart:
window.onload = function () {
var r = Raphael("holder");
var pie = r.g.piechart(350, 350, 256, [56, 104, 158, 23, 15, 6]);
pie.hover(function () {
this.sector.stop();
this.sector.animate({scale: [1.1, 1.1, this.cx, this.cy]}, 500, "bounce");
}, function () {
this.sector.animate({scale: [1, 1, this.cx, this.cy]}, 500, "bounce");
});
};
Essentially, the reason I need to be able to do this, is so I can create some separate anchor triggers to perform the scale animations shown above.
Any help greatly appreciated.
the piechart object provides 3 ways to reach their sectors.
1) each function
pie.each(function(sector, cover, i) {
sector.attr({/*...*/}); //raphael
$(sector.node).foo(); //jquery
});
2) series object (for styling and transforming)
var i = 0; // 0 = 56, 1 = 104, 2 = 158 …
//raphael way to hide the first sector
pie.series.items[i].attr({ opacity : 0 });
//jquery way to hide the first sector
$(pie.series.items[i].node).hide();
whereby i is the index of your data-array
demo: http://jsbin.com/eriqa5/2/edit
3) covers object (for mouse and touch events)
//raphael way to hover the first sector
pie.covers.items[0].hover(...);
//jquery way to hover the first sector
$(pie.covers.items[0].node).hover(...);
demo: http://jsbin.com/eriqa5/4/edit

Categories