marketOverview.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { createGraph, switchPlot } from "../core";
  2. import { months, monthsPretty } from "../staticData/constants";
  3. import { addConfigField, clearChildren, getData, prettyMonthName, query } from "../utils";
  4. import { Graph } from "./graph";
  5. export class MarketOverview implements Graph {
  6. id = "marketOverview";
  7. displayName = "Market Overview";
  8. configFieldIDs = ["month", "ticker"];
  9. loadedData: any;
  10. urlParams: any;
  11. constructor(loadedData: any, urlParams: any) {
  12. this.loadedData = loadedData;
  13. this.urlParams = urlParams;
  14. }
  15. setConfigs(useURLParams?: boolean) {
  16. const updateFunc = switchPlot;
  17. const configDiv = document.getElementById("selectorSubtypes");
  18. if (configDiv) {
  19. clearChildren(configDiv);
  20. }
  21. configDiv?.appendChild(addConfigField("select", "month", "Month: ", {
  22. prettyValues: monthsPretty,
  23. "values": months
  24. }, useURLParams && this.urlParams.month ? this.urlParams.month : months[months.length - 1], updateFunc));
  25. configDiv?.appendChild(addConfigField("input", "ticker", "Ticker: ",
  26. undefined, useURLParams && this.urlParams.ticker ? this.urlParams.ticker : undefined, updateFunc));
  27. }
  28. async generatePlot(configValues: any, plotContainerID: string) {
  29. const ticker = configValues.ticker?.toUpperCase();
  30. if (!ticker) {
  31. return;
  32. }
  33. const companyData = await query("SELECT COALESCE(ci.username, CONCAT(SUBSTR(icp.id, 1, 5), '...')) username, icp.volume, icp.profit, icp.amount FROM IndivCompanyProd icp LEFT JOIN CompanyInfo ci on ci.id = icp.id WHERE icp.ticker = '" + ticker + "' AND icp.month = '" + configValues.month + "'")
  34. const labels = [] as string[];
  35. const parents = [] as string[];
  36. const values = [] as number[];
  37. let totalAmount = 0;
  38. let totalVolume = 0;
  39. let totalProfit = 0;
  40. for (const company of companyData) {
  41. labels.push(company.username);
  42. parents.push("Total");
  43. values.push(company.amount);
  44. totalVolume += company.volume;
  45. totalProfit += company.profit;
  46. totalAmount += company.amount;
  47. }
  48. if (labels.length === 0) {
  49. return;
  50. }
  51. labels.push("Total");
  52. parents.push("");
  53. values.push(totalAmount);
  54. const formatMoney = (num: number) => "$" + num.toLocaleString(undefined, { maximumFractionDigits: 0 });
  55. const title = `${ticker} Market - ${prettyMonthName(configValues.month)}`
  56. + "<br>"
  57. + `Produced per day: ${Math.round(totalAmount).toLocaleString()} ${ticker}`
  58. + "<br>"
  59. + `Volume: ${formatMoney(totalVolume)} | Profit: ${formatMoney(totalProfit)}`;
  60. // Create graph
  61. createGraph(plotContainerID, [{
  62. labels: labels,
  63. values: values,
  64. parents: parents,
  65. type: "treemap",
  66. branchvalues: "total",
  67. tiling: {
  68. pad: 0,
  69. },
  70. textposition: "middle center",
  71. hovertemplate: "%{label}<br>%{value:,.3~s}/day<br>%{percentEntry:.2%}<extra></extra>"
  72. }],
  73. {
  74. title: { text: title },
  75. width: this.urlParams.hideOptions !== undefined ? undefined : 800,
  76. height: this.urlParams.hideOptions !== undefined ? undefined : 400,
  77. autosize: this.urlParams.hideOptions !== undefined,
  78. ...(this.urlParams.hideOptions !== undefined ? {
  79. margin: {
  80. l: 10, // left
  81. r: 10, // right
  82. t: 60, // top
  83. b: 10 // bottom
  84. }
  85. } : {}),
  86. }, {});
  87. }
  88. }