Skip to content

Instantly share code, notes, and snippets.

@ramzs
Last active February 13, 2025 10:33
Show Gist options
  • Save ramzs/906f46e8c1453ae07f3594bc51d1ca1d to your computer and use it in GitHub Desktop.
Save ramzs/906f46e8c1453ae07f3594bc51d1ca1d to your computer and use it in GitHub Desktop.
Graphic svg
<div class="graph">
<svg id="graphic" preserveAspectRatio="none" width="649" height="557" viewBox="0 0 649 557" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 98.1783L4.95 98.1783L4.95 96.7163L11.1205 96.7163L11.1205 88.0518L4.95 88.0518L4.95 86.5898L20 86.5898L20 88.0518L12.3245 88.0518L12.3245 96.7163L20 96.7163L20 98.1783ZM12.3245 75.3917L10.669 75.3917L10.669 74.1877L20 74.1877L20 75.3917L18.409 75.3917C19.0683 75.7643 19.5628 76.2588 19.8925 76.8752C20.2222 77.4772 20.387 78.1293 20.387 78.8317C20.387 80.2937 19.9068 81.469 18.9465 82.3577C17.9862 83.2463 16.7822 83.6907 15.3345 83.6907C13.8725 83.705 12.6685 83.2607 11.7225 82.3577C10.7622 81.4403 10.282 80.2578 10.282 78.8102C10.282 78.0792 10.4468 77.427 10.7765 76.8537C11.1062 76.266 11.6222 75.7787 12.3245 75.3917ZM19.355 78.8317C19.355 77.8427 18.9895 77.0257 18.2585 76.3807C17.5275 75.7213 16.5528 75.3917 15.3345 75.3917C14.2165 75.406 13.2705 75.7285 12.4965 76.3592C11.7082 76.9755 11.314 77.7853 11.314 78.7887C11.314 79.8207 11.6938 80.6663 12.4535 81.3257C13.2132 81.985 14.1735 82.3147 15.3345 82.3147C16.4668 82.329 17.42 82.0137 18.194 81.3687C18.968 80.7237 19.355 79.878 19.355 78.8317ZM10.669 71.0374L10.669 63.5124L20 63.5124L20 64.8024L11.701 64.8024L11.701 69.7474L20 69.7474L20 71.0374L10.669 71.0374ZM20.387 55.8574C20.387 57.3481 19.914 58.5664 18.968 59.5124C18.0077 60.4584 16.7965 60.9314 15.3345 60.9314C13.8868 60.9314 12.6828 60.4584 11.7225 59.5124C10.7622 58.5664 10.282 57.3481 10.282 55.8574C10.282 54.3811 10.7622 53.1699 11.7225 52.2239C12.6828 51.2636 13.8868 50.7834 15.3345 50.7834C16.7965 50.7834 18.0077 51.2636 18.968 52.2239C19.914 53.1699 20.387 54.3811 20.387 55.8574ZM19.355 55.8574C19.3693 54.8397 19.0038 53.9726 18.2585 53.2559C17.4988 52.5249 16.5242 52.1594 15.3345 52.1594C14.1592 52.1594 13.1988 52.5249 12.4535 53.2559C11.7082 53.9726 11.3283 54.8397 11.314 55.8574C11.314 56.8894 11.6938 57.7637 12.4535 58.4804C13.1988 59.1971 14.1592 59.5554 15.3345 59.5554C16.5242 59.5697 17.4917 59.2186 18.237 58.5019C18.9823 57.7709 19.355 56.8894 19.355 55.8574ZM10.669 48.1937L10.669 46.9897L12.3245 46.9897C11.6508 46.6313 11.142 46.1583 10.798 45.5707C10.454 44.983 10.282 44.295 10.282 43.5067C10.282 42.0877 10.755 40.9338 11.701 40.0452C12.6327 39.1422 13.8438 38.6907 15.3345 38.6907C16.7965 38.6907 18.0005 39.1278 18.9465 40.0022C19.8925 40.8765 20.3727 42.0303 20.387 43.4637C20.387 44.1803 20.2365 44.8325 19.9355 45.4202C19.6345 46.0078 19.1758 46.5023 18.5595 46.9037L24.515 46.9037L24.515 48.1937L10.669 48.1937ZM19.355 43.4637C19.355 42.4317 18.9823 41.6075 18.237 40.9912C17.4773 40.3748 16.5098 40.0667 15.3345 40.0667C14.1305 40.081 13.163 40.4107 12.432 41.0557C11.6867 41.7007 11.314 42.5607 11.314 43.6357C11.314 44.6247 11.7082 45.4345 12.4965 46.0652C13.2705 46.6815 14.2165 46.9897 15.3345 46.9897C16.5815 46.9897 17.5633 46.6457 18.28 45.9577C18.9967 45.2697 19.355 44.4383 19.355 43.4637ZM22.881 36.7229L17.592 34.7664L18.3015 33.2614L23.2465 35.9489L22.881 36.7229ZM20 26.8044L9.981 24.5899L18.194 20.7844L9.981 16.9789L20 14.7644L20 16.0544L13.378 17.3874L20.602 20.7844L13.378 24.1814L20 25.5144L20 26.8044Z" fill="black" />
<path d="M523.518 550.715V535.665H527.689C529.18 535.679 530.305 536.023 531.065 536.697C531.824 537.371 532.204 538.352 532.204 539.642C532.204 540.961 531.824 541.964 531.065 542.652C530.305 543.326 529.18 543.656 527.689 543.641H524.98V550.715H523.518ZM524.98 536.869V542.437H527.625C528.628 542.452 529.388 542.222 529.904 541.749C530.42 541.276 530.685 540.574 530.699 539.642C530.699 538.768 530.441 538.087 529.925 537.6C529.424 537.113 528.657 536.869 527.625 536.869H524.98ZM542.505 543.039V541.384H543.709V550.715H542.505V549.124C542.132 549.783 541.637 550.278 541.021 550.607C540.419 550.937 539.767 551.102 539.065 551.102C537.603 551.102 536.427 550.622 535.539 549.661C534.65 548.701 534.206 547.497 534.206 546.049C534.191 544.587 534.636 543.383 535.539 542.437C536.456 541.477 537.638 540.997 539.086 540.997C539.817 540.997 540.469 541.162 541.043 541.491C541.63 541.821 542.118 542.337 542.505 543.039ZM539.065 550.07C540.054 550.07 540.871 549.704 541.516 548.973C542.175 548.242 542.505 547.268 542.505 546.049C542.49 544.931 542.168 543.985 541.537 543.211C540.921 542.423 540.111 542.029 539.108 542.029C538.076 542.029 537.23 542.409 536.571 543.168C535.911 543.928 535.582 544.888 535.582 546.049C535.567 547.182 535.883 548.135 536.528 548.909C537.173 549.683 538.018 550.07 539.065 550.07ZM554.513 548.909V550.263C554.011 550.564 553.524 550.779 553.051 550.908C552.592 551.037 552.119 551.102 551.632 551.102C550.084 551.102 548.801 550.629 547.783 549.683C546.766 548.737 546.264 547.526 546.278 546.049C546.278 544.573 546.773 543.362 547.762 542.416C548.765 541.47 550.048 540.997 551.61 540.997C552.169 540.997 552.685 541.061 553.158 541.19C553.646 541.319 554.097 541.52 554.513 541.792V543.061C553.982 542.703 553.495 542.445 553.051 542.287C552.621 542.115 552.169 542.029 551.696 542.029C550.449 542.029 549.46 542.416 548.729 543.19C548.013 543.964 547.654 544.917 547.654 546.049C547.654 547.268 548.027 548.242 548.772 548.973C549.518 549.704 550.449 550.07 551.567 550.07C552.083 550.07 552.585 549.977 553.072 549.79C553.574 549.604 554.054 549.31 554.513 548.909ZM555.33 550.715L558.792 545.92L555.481 541.384H557.136L559.63 545.017L561.952 541.384H563.457L560.361 545.899L563.823 550.715H562.189L559.544 546.802L556.986 550.715H555.33ZM570.122 551.102C568.632 551.102 567.413 550.629 566.467 549.683C565.521 548.723 565.048 547.511 565.048 546.049C565.048 544.602 565.521 543.398 566.467 542.437C567.413 541.477 568.632 540.997 570.122 540.997C571.599 540.997 572.81 541.477 573.756 542.437C574.716 543.398 575.196 544.602 575.196 546.049C575.196 547.511 574.716 548.723 573.756 549.683C572.81 550.629 571.599 551.102 570.122 551.102ZM570.122 550.07C571.14 550.084 572.007 549.719 572.724 548.973C573.455 548.214 573.82 547.239 573.82 546.049C573.82 544.874 573.455 543.914 572.724 543.168C572.007 542.423 571.14 542.043 570.122 542.029C569.09 542.029 568.216 542.409 567.499 543.168C566.783 543.914 566.424 544.874 566.424 546.049C566.41 547.239 566.761 548.207 567.478 548.952C568.209 549.697 569.09 550.07 570.122 550.07ZM578.625 541.384H584.666V549.683H586.021V553.123H584.817V550.715H577.7V553.123H576.496V549.683C577.213 549.64 577.743 549.346 578.087 548.801C578.445 548.242 578.625 547.289 578.625 545.942V541.384ZM583.376 549.683V542.416H579.915V546.823C579.915 547.468 579.821 548.027 579.635 548.5C579.463 548.973 579.176 549.368 578.775 549.683H583.376ZM587.451 553.596L589.408 548.307L590.913 549.016L588.225 553.961L587.451 553.596ZM605.54 541.384V550.715H604.25V542.416H600.251V547.984C600.251 548.902 599.986 549.59 599.455 550.048C598.939 550.507 598.172 550.729 597.155 550.715V549.683C597.771 549.697 598.223 549.554 598.509 549.253C598.81 548.938 598.961 548.257 598.961 547.21V541.384H605.54ZM607.574 555.23L615.701 534.912H616.905L608.778 555.23H607.574ZM617.799 550.715L620.013 540.696L623.819 548.909L627.624 540.696L629.839 550.715H628.549L627.216 544.093L623.819 551.317L620.422 544.093L619.089 550.715H617.799Z" fill="black" />
<path d="M83.3963 513.508C79.5478 513.508 77.5268 510.433 77.5268 505.553C77.5268 500.672 79.5478 497.598 83.3963 497.598C87.2448 497.598 89.2658 500.672 89.2658 505.553C89.2658 510.433 87.2448 513.508 83.3963 513.508ZM78.1718 505.553C78.1718 510.025 79.8703 512.863 83.3963 512.863C86.9223 512.863 88.6208 510.025 88.6208 505.553C88.6208 501.081 86.9223 498.243 83.3963 498.243C79.8703 498.243 78.1718 501.081 78.1718 505.553Z" fill="black" />
<path d="M50.0366 483.18C46.1881 483.18 44.1671 480.105 44.1671 475.225C44.1671 470.344 46.1881 467.27 50.0366 467.27C53.8851 467.27 55.9061 470.344 55.9061 475.225C55.9061 480.105 53.8851 483.18 50.0366 483.18ZM44.8121 475.225C44.8121 479.697 46.5106 482.535 50.0366 482.535C53.5626 482.535 55.2611 479.697 55.2611 475.225C55.2611 470.753 53.5626 467.915 50.0366 467.915C46.5106 467.915 44.8121 470.753 44.8121 475.225Z" fill="black" />
<path d="M45.499 379.062L44.8755 378.804C45.628 376.632 47.4985 375.278 49.7775 375.278C52.5725 375.278 54.7225 377.277 54.7225 379.9C54.7225 381.728 53.7335 383.491 51.734 385.275L45.9935 390.328H55.088V390.973H44.983V390.392L51.261 384.824C52.938 383.319 54.056 381.685 54.056 379.9C54.056 377.643 52.207 375.923 49.7775 375.923C47.7565 375.923 46.1225 377.127 45.499 379.062Z" fill="black" />
<path d="M53.162 297.194H44.304V296.7L50.3025 285.52H51.055L45.1425 296.549H53.162V291.927H53.807V296.549H56.0215V297.194H53.807V301H53.162V297.194Z" fill="black" />
<path d="M50.0225 208.215C47.077 208.215 44.6905 205.828 44.6905 202.861C44.6905 201.7 45.013 200.69 45.658 199.744L50.5385 192.52H51.3125L47.378 198.325C48.066 197.83 48.9475 197.529 49.8935 197.529C52.839 197.529 55.3975 199.916 55.3975 202.861C55.3975 205.807 52.9895 208.215 50.0225 208.215ZM49.8935 198.174C47.2705 198.174 45.357 200.324 45.357 202.861C45.357 205.463 47.421 207.57 50.0225 207.57C52.6025 207.57 54.731 205.463 54.731 202.861C54.731 200.281 52.495 198.174 49.8935 198.174Z" fill="black" />
<path d="M50.049 117.231C46.523 117.231 44.4805 115.575 44.4805 112.995C44.4805 110.888 45.8995 109.512 48.1355 109.061C46.222 108.566 45.018 107.298 45.018 105.363C45.018 102.89 46.996 101.321 50.049 101.321C53.102 101.321 55.08 102.89 55.08 105.363C55.08 107.298 53.8545 108.566 51.9625 109.061C54.177 109.512 55.596 110.888 55.596 112.995C55.596 115.575 53.5535 117.231 50.049 117.231ZM45.1255 112.995C45.1255 115.188 46.91 116.586 50.049 116.586C53.188 116.586 54.951 115.188 54.951 112.995C54.951 110.759 52.9945 109.405 50.049 109.405C47.082 109.405 45.1255 110.759 45.1255 112.995ZM45.6415 105.363C45.6415 107.47 47.4045 108.76 50.049 108.76C52.672 108.76 54.435 107.47 54.435 105.363C54.435 103.277 52.7365 101.966 50.049 101.966C47.34 101.966 45.6415 103.277 45.6415 105.363Z" fill="black" />
<path d="M39.4853 9.19969L43.9358 6.51219H44.4733V21.9922H43.8283V7.32919L39.8293 9.75869L39.4853 9.19969ZM54.2882 22.2072C50.4397 22.2072 48.4187 19.1327 48.4187 14.2522C48.4187 9.37169 50.4397 6.29719 54.2882 6.29719C58.1367 6.29719 60.1577 9.37169 60.1577 14.2522C60.1577 19.1327 58.1367 22.2072 54.2882 22.2072ZM49.0637 14.2522C49.0637 18.7242 50.7622 21.5622 54.2882 21.5622C57.8142 21.5622 59.5127 18.7242 59.5127 14.2522C59.5127 9.78019 57.8142 6.94219 54.2882 6.94219C50.7622 6.94219 49.0637 9.78019 49.0637 14.2522Z" fill="black" />
<path d="M162.806 501.382L162.183 501.124C162.935 498.952 164.806 497.598 167.085 497.598C169.88 497.598 172.03 499.597 172.03 502.22C172.03 504.048 171.041 505.811 169.041 507.595L163.301 512.648H172.395V513.293H162.29V512.712L168.568 507.144C170.245 505.639 171.363 504.005 171.363 502.22C171.363 499.963 169.514 498.243 167.085 498.243C165.064 498.243 163.43 499.447 162.806 501.382ZM180.918 513.508C177.069 513.508 175.048 510.433 175.048 505.553C175.048 500.672 177.069 497.598 180.918 497.598C184.766 497.598 186.787 500.672 186.787 505.553C186.787 510.433 184.766 513.508 180.918 513.508ZM175.693 505.553C175.693 510.025 177.392 512.863 180.918 512.863C184.444 512.863 186.142 510.025 186.142 505.553C186.142 501.081 184.444 498.243 180.918 498.243C177.392 498.243 175.693 501.081 175.693 505.553Z" fill="black" />
<path d="M261.398 509.487H252.54V508.993L258.539 497.813H259.291L253.379 508.842H261.398V504.22H262.043V508.842H264.258V509.487H262.043V513.293H261.398V509.487ZM271.878 513.508C268.03 513.508 266.009 510.433 266.009 505.553C266.009 500.672 268.03 497.598 271.878 497.598C275.727 497.598 277.748 500.672 277.748 505.553C277.748 510.433 275.727 513.508 271.878 513.508ZM266.654 505.553C266.654 510.025 268.352 512.863 271.878 512.863C275.404 512.863 277.103 510.025 277.103 505.553C277.103 501.081 275.404 498.243 271.878 498.243C268.352 498.243 266.654 501.081 266.654 505.553Z" fill="black" />
<path d="M349.187 513.508C346.242 513.508 343.855 511.121 343.855 508.154C343.855 506.993 344.178 505.983 344.823 505.037L349.703 497.813H350.477L346.543 503.618C347.231 503.123 348.112 502.822 349.058 502.822C352.004 502.822 354.562 505.209 354.562 508.154C354.562 511.1 352.154 513.508 349.187 513.508ZM349.058 503.467C346.435 503.467 344.522 505.617 344.522 508.154C344.522 510.756 346.586 512.863 349.187 512.863C351.767 512.863 353.896 510.756 353.896 508.154C353.896 505.574 351.66 503.467 349.058 503.467ZM362.891 513.508C359.042 513.508 357.021 510.433 357.021 505.553C357.021 500.672 359.042 497.598 362.891 497.598C366.739 497.598 368.76 500.672 368.76 505.553C368.76 510.433 366.739 513.508 362.891 513.508ZM357.666 505.553C357.666 510.025 359.365 512.863 362.891 512.863C366.417 512.863 368.115 510.025 368.115 505.553C368.115 501.081 366.417 498.243 362.891 498.243C359.365 498.243 357.666 501.081 357.666 505.553Z" fill="black" />
<path d="M440.227 513.508C436.701 513.508 434.658 511.852 434.658 509.272C434.658 507.165 436.077 505.789 438.313 505.338C436.4 504.843 435.196 503.575 435.196 501.64C435.196 499.167 437.174 497.598 440.227 497.598C443.28 497.598 445.258 499.167 445.258 501.64C445.258 503.575 444.032 504.843 442.14 505.338C444.355 505.789 445.774 507.165 445.774 509.272C445.774 511.852 443.731 513.508 440.227 513.508ZM435.303 509.272C435.303 511.465 437.088 512.863 440.227 512.863C443.366 512.863 445.129 511.465 445.129 509.272C445.129 507.036 443.172 505.682 440.227 505.682C437.26 505.682 435.303 507.036 435.303 509.272ZM435.819 501.64C435.819 503.747 437.582 505.037 440.227 505.037C442.85 505.037 444.613 503.747 444.613 501.64C444.613 499.554 442.914 498.243 440.227 498.243C437.518 498.243 435.819 499.554 435.819 501.64ZM454.051 513.508C450.202 513.508 448.181 510.433 448.181 505.553C448.181 500.672 450.202 497.598 454.051 497.598C457.899 497.598 459.92 500.672 459.92 505.553C459.92 510.433 457.899 513.508 454.051 513.508ZM448.826 505.553C448.826 510.025 450.525 512.863 454.051 512.863C457.577 512.863 459.275 510.025 459.275 505.553C459.275 501.081 457.577 498.243 454.051 498.243C450.525 498.243 448.826 501.081 448.826 505.553Z" fill="black" />
<path d="M521.729 500.5L526.179 497.813H526.717V513.293H526.072V498.63L522.073 501.059L521.729 500.5ZM536.532 513.508C532.683 513.508 530.662 510.433 530.662 505.553C530.662 500.672 532.683 497.598 536.532 497.598C540.38 497.598 542.401 500.672 542.401 505.553C542.401 510.433 540.38 513.508 536.532 513.508ZM531.307 505.553C531.307 510.025 533.006 512.863 536.532 512.863C540.058 512.863 541.756 510.025 541.756 505.553C541.756 501.081 540.058 498.243 536.532 498.243C533.006 498.243 531.307 501.081 531.307 505.553ZM550.599 513.508C546.751 513.508 544.73 510.433 544.73 505.553C544.73 500.672 546.751 497.598 550.599 497.598C554.448 497.598 556.469 500.672 556.469 505.553C556.469 510.433 554.448 513.508 550.599 513.508ZM545.375 505.553C545.375 510.025 547.073 512.863 550.599 512.863C554.125 512.863 555.824 510.025 555.824 505.553C555.824 501.081 554.125 498.243 550.599 498.243C547.073 498.243 545.375 501.081 545.375 505.553Z" fill="black" />
<path d="M613.204 500.5L617.654 497.813H618.192V513.293H617.547V498.63L613.548 501.059L613.204 500.5ZM622.976 501.382L622.352 501.124C623.105 498.952 624.975 497.598 627.254 497.598C630.049 497.598 632.199 499.597 632.199 502.22C632.199 504.048 631.21 505.811 629.211 507.595L623.47 512.648H632.565V513.293H622.46V512.712L628.738 507.144C630.415 505.639 631.533 504.005 631.533 502.22C631.533 499.963 629.684 498.243 627.254 498.243C625.233 498.243 623.599 499.447 622.976 501.382ZM641.087 513.508C637.239 513.508 635.218 510.433 635.218 505.553C635.218 500.672 637.239 497.598 641.087 497.598C644.936 497.598 646.957 500.672 646.957 505.553C646.957 510.433 644.936 513.508 641.087 513.508ZM635.863 505.553C635.863 510.025 637.561 512.863 641.087 512.863C644.613 512.863 646.312 510.025 646.312 505.553C646.312 501.081 644.613 498.243 641.087 498.243C637.561 498.243 635.863 501.081 635.863 505.553Z" fill="black" />
<line x1="174.875" y1="13.1328" x2="174.876" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line x1="265.857" y1="13.1328" x2="265.857" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line x1="356.838" y1="13.1328" x2="356.838" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line x1="447.819" y1="13.1328" x2="447.819" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line x1="538.801" y1="13.1328" x2="538.801" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line class="line-right" x1="629.782" y1="13.1328" x2="629.782" y2="475.116" stroke="#CDCBCB" stroke-width="2" />
<line class="line-top" x1="628.782" y1="14.1328" x2="84.916" y2="14.1328" stroke="#CDCBCB" stroke-width="2" />
<line x1="628.782" y1="109.156" x2="84.9162" y2="109.156" stroke="#CDCBCB" stroke-width="2" />
<line x1="628.782" y1="200.141" x2="84.9162" y2="200.141" stroke="#CDCBCB" stroke-width="2" />
<line x1="628.782" y1="292.133" x2="84.9162" y2="292.133" stroke="#CDCBCB" stroke-width="2" />
<line x1="628.782" y1="383.113" x2="84.9162" y2="383.113" stroke="#CDCBCB" stroke-width="2" />
<line x1="628.782" y1="474.094" x2="84.9162" y2="474.094" stroke="#CDCBCB" stroke-width="2" />
<path class="line-left" d="M83.9052 13.1328L83.9052 493.312" stroke="#CDCBCB" stroke-width="3" />
<line x1="174.875" y1="474.105" x2="174.875" y2="493.313" stroke="#CDCBCB" stroke-width="2" />
<line x1="265.857" y1="474.105" x2="265.857" y2="493.313" stroke="#CDCBCB" stroke-width="2" />
<line x1="356.838" y1="474.105" x2="356.838" y2="493.313" stroke="#CDCBCB" stroke-width="2" />
<line x1="447.819" y1="474.105" x2="447.819" y2="493.313" stroke="#CDCBCB" stroke-width="2" />
<line x1="538.801" y1="474.105" x2="538.801" y2="493.313" stroke="#CDCBCB" stroke-width="2" />
<line x1="629.782" y1="473.094" x2="629.782" y2="493.312" stroke="#CDCBCB" stroke-width="2" />
<line x1="83.9053" y1="14.1328" x2="64.6981" y2="14.1328" stroke="#CDCBCB" stroke-width="2" />
<line x1="83.9053" y1="109.156" x2="64.6981" y2="109.156" stroke="#CDCBCB" stroke-width="2" />
<line x1="83.9053" y1="200.141" x2="64.6981" y2="200.141" stroke="#CDCBCB" stroke-width="2" />
<line x1="83.9053" y1="292.133" x2="64.6981" y2="292.133" stroke="#CDCBCB" stroke-width="2" />
<line x1="83.9053" y1="383.113" x2="64.6981" y2="383.113" stroke="#CDCBCB" stroke-width="2" />
<line x1="84.9161" y1="474.094" x2="64.6981" y2="474.094" stroke="black" stroke-width="2" />
<line x1="83.9052" y1="60.1328" x2="74.807" y2="60.1328" stroke="#CDCBCB" />
<line x1="83.9052" y1="155.367" x2="74.807" y2="155.367" stroke="#CDCBCB" />
<line x1="83.9052" y1="246.547" x2="74.807" y2="246.547" stroke="#CDCBCB" />
<line x1="83.9052" y1="337.73" x2="74.807" y2="337.73" stroke="#CDCBCB" />
<line x1="83.9052" y1="428.91" x2="74.807" y2="428.91" stroke="#CDCBCB" />
<line x1="492.821" y1="484.215" x2="492.821" y2="475.117" stroke="#CDCBCB" />
<line x1="401.84" y1="484.215" x2="401.84" y2="475.117" stroke="#CDCBCB" />
<line x1="583.802" y1="484.215" x2="583.802" y2="475.117" stroke="#CDCBCB" />
<line x1="310.858" y1="484.215" x2="310.858" y2="475.117" stroke="#CDCBCB" />
<line x1="219.877" y1="484.215" x2="219.877" y2="475.117" stroke="#CDCBCB" />
<line x1="128.896" y1="484.215" x2="128.896" y2="475.117" stroke="#CDCBCB" />
<line x1="128.885" y1="13.1328" x2="128.885" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="219.866" y1="13.1328" x2="219.866" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="310.847" y1="13.1328" x2="310.847" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="401.829" y1="13.1328" x2="401.829" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="492.81" y1="13.1328" x2="492.81" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="583.791" y1="13.1328" x2="583.791" y2="475.116" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="629.537" y1="60.1328" x2="84.1606" y2="60.1328" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="629.537" y1="155.41" x2="84.1606" y2="155.41" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="629.537" y1="246.645" x2="84.1606" y2="246.645" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="629.537" y1="337.879" x2="84.1606" y2="337.879" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line x1="629.537" y1="429.113" x2="84.1606" y2="429.113" stroke="#CDCBCB" stroke-dasharray="4 4" />
<line class="line-bottom" x1="64.698" y1="473.617" x2="628.782" y2="473.617" stroke="#CDCBCB" stroke-width="3" />
<line class="line line_dashed line-2" x1="84.905" y1="306.297" x2="341.696" y2="306.297" stroke="#178AC3" stroke-width="2" stroke-linecap="square" stroke-dasharray="8 8" />
<line class="line line_dashed line-3" x1="343.696" y1="307.297" x2="343.696" y2="473.107" stroke="#178AC3" stroke-width="2" stroke-linecap="square" stroke-dasharray="8 8" />
<path class="line line-1" d="M583.291 473.094C559.385 454.361 535.982 434.764 511.52 416.876C487.067 398.988 462.646 382.79 436.618 365.747C410.601 348.704 381.793 331.69 355.385 314.647C328.976 297.604 303.886 280.561 278.105 263.518C252.355 246.475 223.599 229.461 200.856 212.418C178.123 195.375 161.022 178.332 141.687 161.289C122.403 144.266 103.85 127.223 84.9159 110.18" stroke="#0092D4" stroke-width="3.77338" stroke-miterlimit="10" stroke-linecap="round" />
<g class="point point-1" fill="#E3E4E3">
<rect x="344.718" y="266.871" width="108.167" height="38.414" rx="11" fill="#E3E4E3" />
<text class="point-text" x="350" y="290" fill="black">Значение</text>
</g>
</svg>
</div>
document.addEventListener("DOMContentLoaded", function () {
const svg = document.querySelector("#graphic");
const tooltipGroup = document.querySelector(".point");
const tooltipText = document.querySelector(".point-text");
const tooltipRect = tooltipGroup.querySelector("rect");
const horizontalLine = document.querySelector(".line-2");
const verticalLine = document.querySelector(".line-3");
const graphLine = document.querySelector(".line-1");
const lineLeft = document.querySelector(".line-left"); // Получаем элемент с классом line-left
const lineBottom = document.querySelector(".line-bottom"); // Получаем элемент с классом line-bottom
if (
!svg ||
!tooltipGroup ||
!tooltipText ||
!horizontalLine ||
!verticalLine ||
!graphLine ||
!lineLeft ||
!lineBottom
) {
console.error("Некоторые элементы не найдены в SVG.");
return;
}
function resizeRectToFitText(rect, textElement, padding = 10) {
const textWidth = textElement.getComputedTextLength();
rect.setAttribute("width", textWidth + 2 * padding);
// Центрируем текст
const rectWidth = parseFloat(rect.getAttribute("width"));
const rectX = parseFloat(rect.getAttribute("x"));
const textX = rectX + rectWidth / 2 - textWidth / 2;
textElement.setAttribute("x", textX);
}
// Получаем координаты для остановки пунктирных линий на основе положения элементов SVG
const horizontalLineStopX = lineLeft.getBBox().x + lineLeft.getBBox().width; // Координата X для остановки горизонтальной линии
const verticalLineStopY = lineBottom.getBBox().y; // Координата Y для остановки вертикальной линии
const tooltipWidth = tooltipRect.width.baseVal.value;
const tooltipHeight = tooltipRect.height.baseVal.value;
// Задаем начальные значения координат X и Y
const initialTooltipX = parseFloat(tooltipRect.getAttribute("x"));
const initialTooltipY = parseFloat(tooltipRect.getAttribute("y"));
// Предполагаем, что у вас есть ширина графика
const graphWidth = 500; // Замените на фактическую ширину вашего графика
// ** Определяем фиксированные диапазоны осей **
const xAxisMin = 0; // Начало диапазона оси X
const xAxisMax = 110; // Конец диапазона оси X
const yAxisMin = 0; // Начало диапазона оси Y
const yAxisMax = 8; // Конец диапазона оси Y
// Определяем шаг сетки
const gridStep = 0.1;
// Получаем ограничивающий прямоугольник линии графика
const graphLineBBox = graphLine.getBBox();
// Динамически вычисляем координаты SVG для области графика
const svgXZero = graphLineBBox.x;
const svgYMax = graphLineBBox.y;
const svgXMax = graphLineBBox.x + graphLineBBox.width;
const svgYZero = graphLineBBox.y + graphLineBBox.height;
// Объявляем переменные вне mousemove, чтобы сохранить их значения
let intersectionPoint = { x: 0, y: 0 };
let xValue = "0";
let yValue = "8";
// ** Задаем значения по умолчанию **
const defaultYValue = 3.8; // Дефолтное значение Y
const maxValueY = 8; // Дефолтное значение Y
const xAxisRange = xAxisMax - xAxisMin;
const yAxisRange = yAxisMax - yAxisMin;
// Находим соответствующее значение X на линии графика для заданного Y
const defaultIntersectionY =
svgYMax + ((yAxisMax - defaultYValue) / yAxisRange) * (svgYZero - svgYMax); // Инвертируем ось Y
// Set initial X and Y values
let defaultIntersectionX = svgXZero;
let minDistance = Infinity;
const pathLength = graphLine.getTotalLength();
for (let i = 0; i <= pathLength; i += 1) {
const pt = graphLine.getPointAtLength(i);
const distance = Math.abs(pt.y - defaultIntersectionY);
if (distance < minDistance) {
minDistance = distance;
defaultIntersectionX = pt.x;
}
}
const xAxisValue =
xAxisMin +
((defaultIntersectionX - svgXZero) / (svgXMax - svgXZero)) * xAxisRange;
const xAxisValueStepped = Math.round(xAxisValue / gridStep) * gridStep;
// Форматируем значения - Убираем .0, если это целое число
const formatAxisValue = (value) => {
return Number.isInteger(value) ? value.toString() : value.toFixed(1);
};
xValue = formatAxisValue(xAxisValueStepped);
yValue = formatAxisValue(defaultYValue);
// Обновляем текстовое содержимое элемента (tooltipText) - устанавливаем дефолтные значения
tooltipText.textContent = `${yValue}м / ${xValue}л/мин`;
// Вызываем функцию при загрузке страницы
resizeRectToFitText(tooltipRect, tooltipText);
// Устанавливаем положение пунктирных линий - устанавливаем дефолтное значение
horizontalLine.setAttribute("x2", defaultIntersectionX);
horizontalLine.setAttribute("y1", defaultIntersectionY);
horizontalLine.setAttribute("y2", defaultIntersectionY);
verticalLine.setAttribute("x1", defaultIntersectionX);
verticalLine.setAttribute("x2", defaultIntersectionX);
verticalLine.setAttribute("y1", defaultIntersectionY);
verticalLine.setAttribute("y2", verticalLineStopY);
svg.addEventListener("mousemove", function (event) {
const point = svg.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
const cursorPosition = point.matrixTransform(svg.getScreenCTM().inverse());
// Форматируем значения - Убираем .0, если это целое число
const formatAxisValue = (value) => {
return Number.isInteger(value) ? value.toString() : value.toFixed(1);
};
// Если курсор находится достаточно близко к левому краю, принудительно устанавливаем X = 0
if (cursorPosition.x <= svgXZero) {
xValue = "0";
yValue = formatAxisValue(maxValueY);
tooltipText.textContent = `${yValue}м / ${xValue}л/мин`;
horizontalLine.setAttribute("x2", svgXZero);
horizontalLine.setAttribute("y1", defaultIntersectionY);
horizontalLine.setAttribute("y2", defaultIntersectionY);
verticalLine.setAttribute("x1", svgXZero);
verticalLine.setAttribute("x2", svgXZero);
horizontalLine.setAttribute("y1", defaultIntersectionY);
horizontalLine.setAttribute("y2", verticalLineStopY);
return;
}
// Находим точку пересечения
let minDistance = Infinity;
let closestPoint = { x: svgXZero, y: svgYMax };
const pathLength = graphLine.getTotalLength();
for (let i = 0; i <= pathLength; i += 1) {
const pt = graphLine.getPointAtLength(i);
const distance = Math.abs(pt.x - cursorPosition.x);
if (distance < minDistance) {
minDistance = distance;
closestPoint = pt;
}
}
// Ограничиваем точку пересечения
intersectionPoint = {
x: Math.max(svgXZero, Math.min(svgXMax, closestPoint.x)),
y: Math.max(svgYMax, Math.min(svgYZero, closestPoint.y))
};
// Обновляем пунктирные линии
horizontalLine.setAttribute("x1", horizontalLineStopX);
horizontalLine.setAttribute("x2", intersectionPoint.x);
horizontalLine.setAttribute("y1", intersectionPoint.y);
horizontalLine.setAttribute("y2", intersectionPoint.y);
verticalLine.setAttribute("x1", intersectionPoint.x);
verticalLine.setAttribute("x2", intersectionPoint.x);
verticalLine.setAttribute("y1", intersectionPoint.y);
verticalLine.setAttribute("y2", verticalLineStopY);
// Вычисляем xOffset на основе положения x
let xOffset = 10; // Смещение по умолчанию вправо
if (intersectionPoint.x > graphWidth - 50) {
// Регулируем 50 по необходимости
xOffset = -10 - tooltipWidth; // Смещаем влево
}
// Размещаем tooltipGroup, используя начальные позиции в качестве смещения
tooltipGroup.setAttribute(
"transform",
`translate(${intersectionPoint.x + xOffset - initialTooltipX}, ${
intersectionPoint.y - tooltipHeight / 2 - initialTooltipY
})`
);
// *** Преобразуем координаты SVG в значения осей ***
const xAxisRange = xAxisMax - xAxisMin;
const yAxisRange = yAxisMax - yAxisMin;
const xAxisValue =
xAxisMin +
((intersectionPoint.x - svgXZero) / (svgXMax - svgXZero)) * xAxisRange;
const yAxisValue =
yAxisMax -
((intersectionPoint.y - svgYMax) / (svgYZero - svgYMax)) * yAxisRange; // Инвертируем ось Y
// Применяем шаг сетки
const xAxisValueStepped = Math.round(xAxisValue / gridStep) * gridStep;
const yAxisValueStepped = Math.round(yAxisValue / gridStep) * gridStep;
// Обновляем значения
xValue = formatAxisValue(xAxisValueStepped);
yValue = formatAxisValue(yAxisValueStepped);
// Обновляем текстовое содержимое элемента (tooltipText)
tooltipText.textContent = `${yValue}м / ${xValue}л/мин`;
resizeRectToFitText(tooltipRect, tooltipText); // Вызываем после обновления текста
});
svg.addEventListener("mouseleave", function (event) {
tooltipText.textContent = `${yValue}м / ${xValue}л/мин`; // Сохраняем текстовое содержимое
resizeRectToFitText(tooltipRect, tooltipText); // Вызываем после обновления текста
horizontalLine.setAttribute("x1", horizontalLineStopX); // Сбрасываем горизонтальную линию
verticalLine.setAttribute("y2", verticalLineStopY); // Сбрасываем вертикальную линию
});
});
svg {
display: block;
width: 100%;
max-width: 649px;
height: auto;
}
.graph {
position: relative;
display: inline-flex;
align-items: flex-start;
}
.point {
position: relative;
}
.line-2,
.line-3,
.line-1 {
pointer-events: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment