Last updated

Bar Chart Mode

Bar chart mode provide an easy way to add bar chart to TimeSeriesWidget.

# Add BarMode

This example shows how to create add bar chart for TimeSeriesWidget

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"])
      }
    });
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));

# Bars Rendering Order

This example shows how to chage rendering order of bars of different series. By default, line series was added first will be rendered first, thus any series added later will be rendered on top.

In this example, we have 3 rendering orders:

  • Default: line series added first will be rendered first, so any line series added later will be rendered on top.
  • Reverse: line series added first will be rendered on top, so any line series added later will be rendered behind.
  • Blended: blend between multiple series, so that any bars with smaller values will be rendered on top and be visible.
import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function setRenderingOrder(widget, type) {
  switch (type) {
    case "reverse":
      widget.setOptions({
        "barmode": {
          "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"])
        }
      });
      break;
    case "blended":
      widget.setOptions({
        "barmode": {
          "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["height"] - a["height"])
        }
      });
      break;
    case "default":
      widget.setOptions({
        "barmode": {
          "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => a["order"] - b["order"])
        }
      });
      break;
  }
}
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      }
    });
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene, setRenderingOrder };

createScene(document.querySelector('[ref="plot"]'));

# Highlight Bars With Selection

This example shows how to use TimeSeriesWidget picking tool to add an event to highlight selected bar.

How bar will be highlighted, can be set by passing a function to 'highlightingmethod' property.
In this case, we make bar line style width bigger and set its color black.

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Events as SelectionEvents } from "@int/geotoolkit/controls/tools/Selection.ts";
import { RgbaColor } from "@int/geotoolkit/util/RgbaColor.ts";
import { HsvColor } from "@int/geotoolkit/util/HsvColor.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function highlightingMethodSelection(highlightBar, lineStyle, fillStyle) {
    let rgbacolor = RgbaColor.fromObject(fillStyle.getColor()).setAlpha(1);
    const color = new HsvColor(rgbacolor);
    color.adjustSaturationByFactor(0.4);
    rgbacolor = color.toRgbaColor();
    fillStyle.setColor(rgbacolor);
    return {
      "linestyle": lineStyle,
      "fillstyle": fillStyle
    };
  }
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"]),
        "highlightingmethod": highlightingMethodSelection
      }
    });
    customizeTool(widget);
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  function customizeTool(widget) {
    widget.getToolByName("picking").on(SelectionEvents.onPick, (evt, sender, eventArgs) => {
      const devicePoint = eventArgs.getPlotPoint();
      const lineData = widget.hitTest(devicePoint);
      const transformation = lineData[0]["curve"].getSceneTransform();
      const modelPoint = transformation.inverseTransformPoint(devicePoint);
      const lineIndex = lineData.slice(0).sort((a, b) => a["value"] - b["value"]).findIndex((data) => modelPoint.getY() <= data["value"]);
      if (lineIndex < 0) {
        widget.highlightBars([]);
        return;
      }
      widget.highlightBars([{
        "lineindex": lineIndex,
        "datapointindex": lineData[lineIndex]["index"]
      }]);
    });
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));

# Highlight Bars When Pointer Move

This example shows how to use TimeSeriesWidget cursor tool to add an event to highlight bar pointer is hovering over.

How bar will be highlighted, can be set by passing a function to 'highlightingmethod' property.
In this case, we make bar line style width bigger and set its color to the color of its fill style while also remove color alpha.
This is an eazy way to make highlighted bar looks larger.

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Events as CrossHairEvents } from "@int/geotoolkit/controls/tools/CrossHair.ts";
import { RgbaColor } from "@int/geotoolkit/util/RgbaColor.ts";
import { HsvColor } from "@int/geotoolkit/util/HsvColor.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function highlightingMethodPositionChanged(highlightBar, lineStyle, fillStyle) {
    let rgbacolor = RgbaColor.fromObject(fillStyle.getColor()).setAlpha(1);
    const color = new HsvColor(rgbacolor);
    color.adjustSaturationByFactor(0.7);
    rgbacolor = color.toRgbaColor();
    lineStyle.setWidth(5).setColor(rgbacolor);
    fillStyle.setColor(rgbacolor);
    return {
      "linestyle": lineStyle,
      "fillstyle": fillStyle
    };
  }
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"]),
        "highlightingmethod": highlightingMethodPositionChanged
      }
    });
    customizeTool(widget);
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  function customizeTool(widget) {
    widget.getToolByName("cursor").on(CrossHairEvents.onPositionChanged, (evt, sender, eventArgs) => {
      const devicePoint = eventArgs.getPlotPoint();
      const lineData = widget.hitTest(devicePoint);
      const transformation = lineData[0]["curve"].getSceneTransform();
      const modelPoint = transformation.inverseTransformPoint(devicePoint);
      const lineIndex = lineData.slice(0).sort((a, b) => a["value"] - b["value"]).findIndex((data) => modelPoint.getY() <= data["value"]);
      if (lineIndex < 0) {
        widget.highlightBars([]);
        return;
      }
      widget.highlightBars([{
        "lineindex": lineIndex,
        "datapointindex": lineData[lineIndex]["index"]
      }]);
    });
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));

# Bar Mode With Stack Mode

This example shows how to create add bar chart combines with stack mode for TimeSeriesWidget

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"]),
        "barvaluevisibility": 40
      },
      "stack": {
        "enabled": true
      }
    });
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));

# Bar Mode With Percent Mode

This example shows how to create add bar chart combines with percent mode for TimeSeriesWidget

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    widget.scaleModel(2);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"])
      },
      "percent": {
        "enabled": true
      }
    });
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));

# Customization

This example shows some possible customizations can be used with TimeSeriesWidget barmode.

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { Events as CrossHairEvents } from "@int/geotoolkit/controls/tools/CrossHair.ts";
import { RgbaColor } from "@int/geotoolkit/util/RgbaColor.ts";
import { HsvColor } from "@int/geotoolkit/util/HsvColor.ts";
import { getDataTables } from "/src/code/TimeSeries/data.ts";
function createScene(canvas) {
  const startDate = new Date(2013, 0, 1).getTime();
  const endDate = new Date(2014, 0, 1).getTime();
  const dataTableViews = getDataTables(startDate, endDate);
  const curveIndice = [0, 1];
  const names = ["CALI", "GR"];
  const colors = [
    "rgba(21, 101, 192, 0.85)",
    "rgba(239, 108, 0, 0.85)"
  ];
  function highlightingMethodPositionChanged(highlightBar, lineStyle, fillStyle) {
    let rgbacolor = RgbaColor.fromObject(fillStyle.getColor()).setAlpha(1);
    const color = new HsvColor(rgbacolor);
    color.adjustSaturationByFactor(0.7);
    rgbacolor = color.toRgbaColor();
    lineStyle.setWidth(5).setColor(rgbacolor);
    fillStyle.setColor(rgbacolor);
    return {
      "linestyle": lineStyle,
      "fillstyle": fillStyle
    };
  }
  function createWidget() {
    const options = {
      "title": {
        "visible": false
      },
      "model": new Group().setModelLimits(new Rect(startDate, 0, endDate, 1)),
      "curveaxis": {
        "visible": true,
        "autocoloraxis": true,
        "autocolorlabel": true,
        "titlevisible": true,
        "axiswidth": 30,
        "compact": true
      },
      "curvelimits": {
        "visible": false
      }
    };
    const widget = new TimeSeriesWidget(options);
    curveIndice.forEach((curveIndex, index) => {
      widget.addCurve({
        "name": names[index],
        "uri": "//test//" + names[index].toLowerCase(),
        "data": dataTableViews[curveIndex],
        "properties": {
          "autoscale": true,
          "axisautolabelrotation": true,
          "neatlimits": true,
          "unit": "INS",
          "linestyle": {
            "color": colors[index],
            "width": 2
          },
          "barmode": {
            "enabled": true,
            "fillstyle": colors[index],
            "linestyle": colors[index],
            "barvalues": {
              "textstyle": {
                "font": "12px Roboto"
              }
            }
          }
        }
      });
    });
    widget.setOptions({
      "lastupdatedate": {
        "followcursor": true
      },
      "barmode": {
        "renderingorder": (valueOrderPairs) => valueOrderPairs.sort((a, b) => b["order"] - a["order"]),
        "highlightingmethod": highlightingMethodPositionChanged,
        "barvaluevisibility": 40
      }
    });
    customizeTool(widget);
    widget.scaleModel(8).translateModel(700);
    return widget;
  }
  function customizeTool(widget) {
    widget.getToolByName("cursor").on(CrossHairEvents.onPositionChanged, (evt, sender, eventArgs) => {
      const lineData = widget.hitTest(eventArgs.getPlotPoint());
      widget.highlightBars(lineData.map((data, index) => {
        const dataPointIndex = data["index"];
        return {
          "lineindex": index,
          "datapointindex": dataPointIndex
        };
      }));
    });
  }
  return new Plot({
    "canvaselement": canvas,
    "root": createWidget()
  });
}
export { createScene };

createScene(document.querySelector('[ref="plot"]'));