prettify

baseline

SVG Javascript with events

I need a widget displaying the months of the year. I implemented using SVG and not by Canvas because I needed the capability of SVG to assign events to any element of the picture.
  • The user should be able to select a month by clicking on it
  • The widget should give an event for every month change
  • The user should be able to deselect a month by clicking on it or at the center of the wheel.
It really works! Try it.
JanFebMarAprMayJunJulAugSepOctNovDec
Usage (MonthWheel.htm):
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>svg</title>
  5. <script type="text/javascript" src="dom.js"></script>
  6. <script type="text/javascript" src="MonthWheel.js"></script>
  7. <script type="text/javascript">
  8. window.onload = function () {
  9.     var oWheel = new MonthWheel($("divSeasons"), 400, 400);
  10.     oWheel.eLang = "en";
  11.     oWheel.MonthChanged = function () {
  12.         if (oWheel.nMonth === -1) return;
  13.         $("divChanges").a$({
  14.             t: MonthWheel.Months[oWheel.nMonth][oWheel.eLang]+ " "});
  15.     };
  16.     oWheel.Show();
  17. };
  18. </script>
  19. </head>
  20. <body>
  21. <div id="divSeasons"></div>
  22. <div id="divChanges"></div>
  23. </body>
  24. </html>
The code for dom.js is in an older post. MontWheel.js:
  1. function MonthWheel(oContainer,nWidth,nHeight) {
  2.     var that = this;
  3.     this.oContainer = oContainer;
  4.     this.eLang = "en";
  5.     this.nWidth = 100;
  6.     this.nHeight = 100;
  7.     this.nMonth = -1;
  8.     //events
  9.     this.MonthChanged =null;
  10.     if (typeof nWidth === "number") {
  11.         this.nWidth = nWidth;
  12.         if (typeof nHeight === "number") {
  13.             this.nHeight = nHeight;
  14.         }
  15.     }
  16.     this.SelectMonth = function () {
  17.         var nMonth = parseInt(this.attributes["nMonth"].nodeValue);
  18.         nMonth = (nMonth === that.nMonth) ? -1 : nMonth;
  19.         that.SetMonth(nMonth);

  20.     };
  21.     this.SetMonth = function (nMonth) {
  22.         if (typeof nMonth !== "number") nMonth = -1;
  23.         if (nMonth === that.nMonth) return;
  24.         that.nMonth = nMonth;
  25.         that.Show();
  26.         if (typeof that.MonthChanged === "function") that.MonthChanged();
  27.     }
  28. }
  29. MonthWheel.Months=[
  30.     { en: "Jan", el: "Ιαν", color: "44f", stroke: "008" }
  31.     , { en: "Feb", el: "Φεβ", color: "08f", stroke: "048" }
  32.     , { en: "Mar", el: "Μαρ", color: "0f8", stroke: "084" }
  33.     , { en: "Apr", el: "Απρ", color: "4f4", stroke: "080" }
  34.     , { en: "May", el: "Μαι", color: "8f4", stroke: "480" }
  35.     , { en: "Jun", el: "Ιουν", color: "cf0", stroke: "680" }
  36.     , { en: "Jul", el: "Ιουλ", color: "ff0", stroke: "880" }
  37.     , { en: "Aug", el: "Αυγ", color: "fc0", stroke: "860" }
  38.     , { en: "Sep", el: "Σεπ", color: "f80", stroke: "840" }
  39.     , { en: "Oct", el: "Οκτ", color: "f44", stroke: "800" }
  40.     , { en: "Nov", el: "Νοε", color: "f48", stroke: "804" }
  41.     , { en: "Dec", el: "Δεκ", color: "84f", stroke: "408" }
  42. ];
  43. MonthWheel.prototype.Show = function () {
  44.     var oFra = document.createDocumentFragment();
  45.     var nRadius = 1000, nRad = 1000;
  46.     var oSvg = oFra.a$("svg:svg", {
  47.         width: this.nWidth.toString() + "px",
  48.         height: this.nHeight.toString() + "px",
  49.         viewBox: "-" + (nRadius + 100).toString() +
  50.         " -" + (nRadius + 100).toString() +
  51.         " " + (2 * (nRadius + 100)).toString() +
  52.         " " + (2 * (nRadius + 100)).toString()
  53.     });
  54.     var nMonth = 0, oMonth, oPath, oText;
  55.     var nX, nY, nAngle = 0, nAngle2 = Math.PI / 6;
  56.     oSvg.a$("svg:circle", { r: nRadius, style:"fill:#ccc;cursor:pointer;"
  57.         }).onclick = this.SetMonth;
  58.     for (nMonth = 0; nMonth < 12; nMonth++) {
  59.         nRad = (nMonth === this.nMonth) ? nRadius * 1.07 : nRadius;
  60.         oMonth = MonthWheel.Months[nMonth];
  61.         nAngle = nMonth * Math.PI / 6;
  62.         nX = nRad * Math.sin(nAngle);
  63.         nY = -1 * nRad * Math.cos(nAngle);
  64.         nX2 = nRad * Math.sin(nAngle + Math.PI / 6);
  65.         nY2 = -1 * nRad * Math.cos(nAngle + Math.PI / 6);
  66.         oPath = oSvg.a$("svg:path", {
  67.             id: "pat" + oMonth.en,
  68.             nMonth: nMonth,
  69.             style: "fill:#" + oMonth.color + ";stroke:#" + oMonth.stroke +
  70.                 ";strokeWidth:20;cursor:pointer;",
  71.             d: "M" +
  72.             nX.toString() + "," + nY.toString() +
  73.             " A" + nRad.toString() + "," + nRad.toString() + " 0 0 1 " +
  74.             nX2.toString() + "," + nY2.toString() +
  75.             " L" + (nX2 / 2).toString() + "," + (nY2 / 2).toString() +
  76.             " A " + (nRad / 2).toString() + "," + (nRad / 2).toString() + " 0 0 0 " +
  77.             (nX / 2).toString() + "," + (nY / 2).toString() + " z"
  78.         });
  79.         oPath.onclick = this.SelectMonth;
  80.         oText = oSvg.a$("svg:text", { x: (nX + nX2) * 3 / 8, y: (nY + nY2) * 3 / 8,
  81.             t: oMonth[this.eLang], nMonth: nMonth,
  82.             style:"fontSize:100px;textAnchor:middle;cursor:pointer;color:#ccc;" });
  83.         oText.onclick = this.SelectMonth;
  84.     }
  85.     this.oContainer.innerHTML = "";
  86.     this.oContainer.appendChild(oFra);
  87. }

No comments:

Post a Comment