FileAttachmentDynamic = function(filename) {
return new Function("FileAttachment", `return FileAttachment("${filename}")`)(FileAttachment)
}
// Vaihdetaan tekstin väri
color = function(vari) {
if(vari > 0){
return "green"
}else{
return "red"
}
}
// Pyöristys
pyoristys = function(n, places) {
if (!places) return Math.round(n);
const d = 10 ** places;
return Math.round(n * d) / d;
}
//Euromerkintä
eurot = function(number) {
return number.toLocaleString('fi-FI', { style: 'currency', currency: 'EUR',minimumFractionDigits: 0 });
}
// Euromuutoksen laskeminen kertoimella
muutoskerroin = function(x, y) {
return (1+x/100)*y;
}
// Muutosprosentti
muutosprosentti = function(x, y) {
return pyoristys(((x-y)/y)*100,1);
}
// Tuhatjakaja
tuhatjakaja = function(x) {
return x/1000;
}
// Euromuutoksen laskeminen kertoimella
palkkakerroin = function(x, y) {
return 100*((1+x/100)*(1+y/100)-1);
}
// Jako-osuuden asukaskerroin
asukaskerroin = function(x, y) {
return (x/y);
}
// Jako-osuuden veroprosenttikerroin miinus1/miinus3 vuotta miinus 1 vuoden kerroin
veroprosenttikerroin = function(x, y) {
return (x/y);
}
// Kunnan muok. kunnallisvero, alkuvuosi ja loppuvuosi
kunnallisvero_muokkaus = function(kunnallisvero,asukaskerroin,veroprosentti) {
return kunnallisvero*asukaskerroin*veroprosentti;
}
//Tekstimuutokset
fn_nousu_lasku_txt = function(arvo){
if(arvo > 0) {
return "kasvanut"
}
else {
return "laskenut";
}
}
//TARVITAAN KARTOISSA
serialize = {
const xmlns = "http://www.w3.org/2000/xmlns/";
const xlinkns = "http://www.w3.org/1999/xlink";
const svgns = "http://www.w3.org/2000/svg";
return function serialize(svg) {
svg = svg.cloneNode(true);
const fragment = window.location.href + "#";
const walker = document.createTreeWalker(svg, NodeFilter.SHOW_ELEMENT);
while (walker.nextNode()) {
for (const attr of walker.currentNode.attributes) {
if (attr.value.includes(fragment)) {
attr.value = attr.value.replace(fragment, "#");
}
}
}
svg.setAttributeNS(xmlns, "xmlns", svgns);
svg.setAttributeNS(xmlns, "xmlns:xlink", xlinkns);
const serializer = new window.XMLSerializer;
const string = serializer.serializeToString(svg);
return new Blob([string], {type: "image/svg+xml"});
};
}
function toSVG(chart) {
if (chart.nodeName !== "FIGURE") {
return chart;
}
// the chart needs to be in the body if we want to read values, positions, sizes…
document.body.appendChild(chart);
const [x0, y0, width, height] = getBounds([chart]);
const nodes = [];
for (const node of d3
.select(chart)
.selectChildren("h1,h2,h3,div,figcaption,svg")) {
switch (node.nodeName.toLowerCase()) {
case "div":
{
const children = d3.select(node).selectChildren("div,span");
const height = getBounds([node, ...children])[3] + 2;
const svg = d3
.select(chart)
.append("svg")
.attr("width", width)
.attr("height", height);
nodes.push(svg.node());
const swatches = svg
.selectAll()
.data(
Array.from(children, (d) => {
const svg = d3.select(d).select("svg").node();
const bbox = svg.getBBox();
return {
style: window.getComputedStyle(d),
svg,
width: bbox.width,
height: bbox.height,
text: d.textContent,
bounds: getBounds([d])
};
})
)
.join("g")
.attr(
"transform",
(d) => `translate(${d.bounds[0] - x0},${10 + d.bounds[1] - y0})`
);
swatches
.append((d) => d.svg) // "rect")
.attr("width", (d) => d.width)
.attr("height", (d) => d.height)
.attr("y", (d) => `${-parseFloat(d.height) / 2}px`);
swatches
.append("text")
.text((d) => d.text)
.attr("x", (d) => d.width)
.attr("dx", 5)
.attr("dy", "0.38em")
.attr("font-family", (d) => d.style.fontFamily)
.attr("font-size", (d) => d.style.fontSize)
.attr("fill", (d) => d.style.color);
}
break;
case "figcaption":
case "h1":
case "h2":
case "h3":
{
const svg = d3
.select(chart)
.append("svg")
.attr("width", width)
.attr("overflow", "visible");
nodes.push(svg.node());
const children = d3.select(node).selectChildren();
let h = 0;
for (const d of children.size() > 0
? children.selectChildren()
: [node]) {
const style = window.getComputedStyle(d);
const t = svg
.append("g")
.attr("transform", `translate(0,${h})`)
.append(() =>
d3
.select(
Plot.text([d.textContent], {
text: (d) => d,
lineWidth:
(1.06 * parseFloat(style.width)) /
parseFloat(style.fontSize),
lineHeight: 1.2,
frameAnchor: "top-left"
}).plot()
)
.select("text")
.attr("font-family", style.fontFamily)
.attr("font-size", 1.08 * parseFloat(style.fontSize))
.attr("font-weight", style.fontWeight)
.attr("fill", style.color)
.node()
);
h += getBounds([t.node()])[3] + 4;
}
svg.attr("height", h);
}
break;
case "svg":
d3.select(chart).append(() => node);
nodes.push(node);
break;
}
}
return serializeAll(nodes)
.then((blob) => blob.text())
.then((c) => {
document.body.removeChild(chart);
return Object.assign(svg`${c}`, chart);
});
}
// Given an array of SVG elements, composites them into a single SVG element,
// and then serializes the result to a blob.
async function serializeAll(elements, {padding = 10} = {}) {
const fragment = location.href + "#";
let root;
if (elements.length === 1) {
root = elements[0].cloneNode(true); // optimize common case
} else {
const [ox, oy, dx, dy] = getBounds(elements);
root = document.createElementNS(svgns, "svg");
root.setAttribute("width", dx + 2 * padding);
root.setAttribute("height", dy + 2 * padding);
root.setAttribute("viewBox", [-padding, -padding, dx + 2 * padding, dy + 2 * padding]);
for (const element of elements) {
const svg = root.appendChild(element.cloneNode(true));
const { x, y, width, height } = element.getBoundingClientRect();
svg.setAttribute("x", x - ox);
svg.setAttribute("y", y - oy);
svg.setAttribute("width", width);
svg.setAttribute("height", height);
}
}
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
while (walker.nextNode()) {
const node = walker.currentNode;
for (const attr of node.attributes) {
if (attr.value.includes(fragment)) {
attr.value = attr.value.replace(fragment, "#");
}
}
}
root.setAttributeNS(xmlns, "xmlns", svgns);
root.setAttributeNS(xmlns, "xmlns:xlink", xlinkns);
const serializer = new XMLSerializer();
const string = serializer.serializeToString(root);
return new Blob([string], { type: "image/svg+xml" });
}
function getBounds(elements) {
let x1 = Infinity;
let y1 = x1;
let x2 = -x1;
let y2 = x2;
for (const element of elements) {
const { x, y, width, height } = element.getBoundingClientRect();
if (x < x1) x1 = x;
if (x + width > x2) x2 = x + width;
if (y < y1) y1 = y;
if (y + height > y2) y2 = y + height;
}
return [x1, y1, x2 - x1, y2 - y1];
}
// based on https://observablehq.com/@gka/cheap-fit-text-to-circle
function lines(text, targetWidth) {
const CHAR_W = {
"a":7,"B":8,"C":8,"c":6,"D":9,"f":4,"G":9,"H":9,"I":3,"i":3,"J":5,"j":3,"K":8,"k":6,
"l":3,"M":11,"m":11,"N":9,"O":9,"P":8,"Q":9,"R":8,"r":4,"S":8,"s":6,"t":4,"U":9,"v":6,
"W":11,"w":9,"x":6,"y":6,"z":5,".":2,",":2,":":2,";":2
};
function measureWidth(text) { return d3.sum(text, char => CHAR_W[char] || CHAR_W["a"]) * 0.8; };
const words = text.split(" ");
let line;
let lineWidth0 = Infinity;
const lines = [];
for (let i = 0, n = words.length; i < n; ++i) {
let lineText1 = (line ? line.text + " " : "") + words[i];
let lineWidth1 = measureWidth(lineText1);
if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
line.width = lineWidth0 = lineWidth1;
line.text = lineText1;
} else {
lineWidth0 = measureWidth(words[i]);
line = {width: lineWidth0, text: words[i]};
lines.push(line);
}
}
return lines;
}
xmlns = "http://www.w3.org/2000/xmlns/"
xlinkns = "http://www.w3.org/1999/xlink"
svgns = "http://www.w3.org/2000/svg"
Avainsanat
Kuntien talouden neljännesvuosiraportti, talous, yhteistyö, avoin lähdekoodi, Tutkihallintoa.fi, tietojohtaminen
Toimintatulot
Tuet ja avustukset
Tuet, avustukset ja muut tulonsiirrot valtiolta, Euroopan unionilta tai muulta yhteisöltä merkitään tuloslaskelmaan omaksi ryhmäkseen silloin, kun tuki tai avustus ei ole kunnan suoritteidensa perusteella saama korvaus eikä investoinnin rahoitusosuus. Tällaisia korvauksia ovat mm. valtionavustus perustoimeentulotukeen, palkkatuki sekä EU-tuki kunnan omaan käyttötalouden kehittämisprojektiin.
Maksutulot
Maksutuloja ovat asiakasmaksut ja muut maksut niistä tavaroista ja palveluista, joiden hinnoittelun tarkoituksena ei ole kattaa tuotantokustannuksia kokonaisuudessaan tai joiden hinnat määritellään asiakkaan maksukyvyn mukaan. Usein maksujen perusteista säädetään laissa tai asetuksessa.
Muut toimintatulot
Muihin toimintatuloihin sisältyvät muut kuin edellä mainitut säännöllisesti kertyvät toimintatulot. Tällaisia ovat mm. vuokratulot sekä pysäköintivirhemaksut.
Myyntitulot
Myyntituloja ovat tulot tavaroista ja palveluksista, jotka on tarkoitettu myytäväksi pääsääntöisesti tuotantokustannukset peittävään hintaan.(Lähde: Tutkihallintoa.fi 2024)
Toimintatulot
Toimintatuotot € per asukas
Lähteet
Tutkihallintoa.fi. 2024. Kuntatalouden ABC. Tutkihallintoa.fi. https://www.tutkihallintoa.fi/kuntatalouden-abc/.