All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pepstock.charba.client.data.Data Maven / Gradle / Ivy

/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at
    
      http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
package org.pepstock.charba.client.data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.pepstock.charba.client.ChartEnvelop;
import org.pepstock.charba.client.Configuration;
import org.pepstock.charba.client.ConfigurationElement;
import org.pepstock.charba.client.IsChart;
import org.pepstock.charba.client.callbacks.DatasetContext;
import org.pepstock.charba.client.colors.CanvasObject;
import org.pepstock.charba.client.colors.Gradient;
import org.pepstock.charba.client.colors.Pattern;
import org.pepstock.charba.client.commons.ArrayMixedObject;
import org.pepstock.charba.client.commons.ArrayObjectContainerList;
import org.pepstock.charba.client.commons.ArrayUtil;
import org.pepstock.charba.client.commons.ConfigurationLoader;
import org.pepstock.charba.client.commons.Constants;
import org.pepstock.charba.client.commons.Envelop;
import org.pepstock.charba.client.commons.Key;
import org.pepstock.charba.client.commons.NativeObjectContainer;
import org.pepstock.charba.client.items.ActiveDatasetElement;
import org.pepstock.charba.client.items.LegendItem;
import org.pepstock.charba.client.items.TooltipItem;
import org.pepstock.charba.client.items.Undefined;

/**
 * CHART.JS entity object to configure the data options of a chart.
* It contains labels and data sets. * * @author Andrea "Stock" Stocchero */ public final class Data extends NativeObjectContainer implements ConfigurationElement, HasLabels { /** * Name of properties of native object. */ private enum Property implements Key { DATASETS("datasets"), X_LABELS("xLabels"), Y_LABELS("yLabels"); // name value of property private final String value; /** * Creates with the property value to use in the native object. * * @param value value of property name */ private Property(String value) { this.value = value; } /* * (non-Javadoc) * * @see org.pepstock.charba.client.commons.Key#value() */ @Override public String value() { return value; } } // chart instance private final IsChart chart; // maintains the list of data sets because needs to preserve the data set type private final ArrayObjectContainerList currentDatasets = new ArrayObjectContainerList<>(); // instance of labels option handler private final LabelsHandler labelsHandler; // flag to disable canvas object handler private boolean canvasObjectHandling = true; /** * Creates the object with an empty native object. * * @param envelop envelop containing the chart instance */ public Data(ChartEnvelop envelop) { this.chart = Envelop.checkAndGetIfValid(envelop).getContent(); // creates the labels option manager this.labelsHandler = new LabelsHandler(getNativeObject()); } /* * (non-Javadoc) * * @see org.pepstock.charba.client.data.HasLabels#getLabelsHandler() */ @Override public LabelsHandler getLabelsHandler() { return labelsHandler; } /** * Sets the labels for X axes of the data. * * @param labels array of labels */ public void setXLabels(String... labels) { // creates a label object Labels internalLabels = Labels.build(); // loads internalLabels.load(labels); // sets X labels setXLabels(internalLabels); } /** * Sets the labels for X axes of the data. * * @param labels labels object to manage also multi-line labels */ public void setXLabels(Labels labels) { // checks if argument is consistent if (labels != null && !labels.getArray().isEmpty()) { setArrayValue(Property.X_LABELS, labels.getArray()); } } /** * Returns the labels for X axes. * * @return the labels for X axes */ public Labels getXLabels() { return getXLabels(false); } /** * Returns the labels for X axes. * * @param binding if true binds the new labels in the container * @return the labels for X axes */ public Labels getXLabels(boolean binding) { // checks if there is the property if (has(Property.X_LABELS)) { // gets array ArrayMixedObject array = getArrayValue(Property.X_LABELS); // returns labels return Labels.load(array); } // if here, no array stored // object to return Labels result = Labels.build(); // checks if binding new array if (binding) { // stores array setXLabels(result); } // returns labels return result; } /** * Sets the labels for Y axes of the data. * * @param labels array of labels */ public void setYLabels(String... labels) { // creates a label object Labels internalLabels = Labels.build(); // loads internalLabels.load(labels); // sets Y labels setYLabels(internalLabels); } /** * Sets the labels for Y axes of the data. * * @param labels labels object to manage also multiple line labels */ public void setYLabels(Labels labels) { // checks if argument is consistent if (labels != null && !labels.getArray().isEmpty()) { setArrayValue(Property.Y_LABELS, labels.getArray()); } } /** * Returns the labels for Y axes. * * @return the labels for Y axes */ public Labels getYLabels() { return getYLabels(false); } /** * Returns the labels for Y axes. * * @param binding if true binds the new labels in the container * @return the labels for Y axes */ public Labels getYLabels(boolean binding) { // checks if there is the property if (has(Property.Y_LABELS)) { // gets array ArrayMixedObject array = getArrayValue(Property.Y_LABELS); // returns labels return Labels.load(array); } // if here, no array stored // object to return Labels result = Labels.build(); // checks if binding new array if (binding) { // stores array setYLabels(result); } // returns labels return result; } /** * Sets a set of data sets for chart. If argument is null, removes all data sets. * * @param datasets set of data set. If null, removes all data sets */ public void setDatasets(Dataset... datasets) { // clear buffer this.currentDatasets.clear(); // checks if arguments is consistent if (datasets != null) { // checks datasets consistent this.chart.checkDatasets(datasets); // adds all data sets this.currentDatasets.addAll(datasets); // sets data sets to native object setArrayValue(Property.DATASETS, this.currentDatasets); } else { // removes the existing property remove(Property.DATASETS); } } /** * Returns the list of data sets. * * @return the list of data sets */ public List getDatasets() { return getDatasets(false); } /** * Returns the list of data sets. * * @param binding if true binds the new array list in the container * @return the list of data sets */ public List getDatasets(boolean binding) { // there is not the property and the binding is requested // then adds array to container if (!has(Property.DATASETS) && binding) { // sets data sets to native object setArrayValue(Property.DATASETS, this.currentDatasets); } // returns data sets return this.currentDatasets; } /** * Returns true if the plugin to manage canvas object (gradients and patterns) has been forcedly disable.
* Pay attention that disabling the handler, your data sets configuration with gradients or patterns will e showed with default color. * * @return true if the plugin to manage canvas object (gradients and patterns) has been forcedly disable */ public boolean isCanvasObjectHandling() { return canvasObjectHandling; } /** * Sets true if the plugin to manage canvas object (gradients and patterns) have to be forcedly disable.
* Pay attention that disabling the handler, your data sets configuration with gradients or patterns will e showed with default color. * * @param canvasObjectHandling true if the plugin to manage canvas object (gradients and patterns) have to be forcedly disable */ public void setCanvasObjectHandling(boolean canvasObjectHandling) { this.canvasObjectHandling = canvasObjectHandling; } /** * Creates a list of active elements instances by an array of data set indexes, for visible data sets. * * @param datasetIndexes an array of data set indexes * @return a list of active elements instances by an array of data set indexes */ public List createActiveElementsByDatasetIndex(int... datasetIndexes) { // creates results List result = new ArrayList<>(); // checks if argument is consistent if (ArrayUtil.isNotEmpty(datasetIndexes)) { // normalizes array int[] indexes = Arrays.stream(datasetIndexes).distinct().toArray(); // scans indexes for (int i = 0; i < indexes.length; i++) { // gets index int index = indexes[i]; // checks if the index is consistent if (index >= 0 && index < currentDatasets.size() && chart.isDatasetVisible(index)) { // gets data set Dataset dataset = currentDatasets.get(index); // scans to add active element for (int k = 0; k < dataset.getDataCount(); k++) { // creates and add active element result.add(new ActiveDatasetElement(index, k)); } } } return result; } // if here, argument is not consistent // then returns an empty list return result; } /** * Creates a list of active elements instances by an array of data indexes, for all visible data sets. * * @param dataIndexes an array of data indexes * @return a list of active elements instances by an array of data indexes */ public List createActiveElementsByDataIndex(int... dataIndexes) { // creates results List result = new ArrayList<>(); // checks if argument is consistent if (ArrayUtil.isNotEmpty(dataIndexes)) { // normalizes array int[] indexes = Arrays.stream(dataIndexes).distinct().toArray(); // data set index int datasetIndex = 0; // scans all data sets for (Dataset dataset : currentDatasets) { checkAndLoadActiveElementForDataset(dataset, datasetIndex, indexes, result); // increments data set index datasetIndex++; } return result; } // if here, argument is not consistent // then returns an empty list return result; } /** * Manages every single data set adding a {@link ActiveDatasetElement} is consistent. * * @param dataset data set instance to manage * @param datasetIndex data set index * @param indexes indexes required * @param result list of {@link ActiveDatasetElement} to return */ private void checkAndLoadActiveElementForDataset(Dataset dataset, int datasetIndex, int[] indexes, List result) { // checks if data set is visible if (chart.isDatasetVisible(datasetIndex)) { // scans all indexes for (int i = 0; i < indexes.length; i++) { // gets index int index = indexes[i]; // checks if the index is consistent if (index >= 0 && index < dataset.getDataCount()) { // creates and add active element result.add(new ActiveDatasetElement(datasetIndex, index)); } } } } /** * Returns a gradient object set as background color for a data set related to legend item. * * @param legendItem legend item instance to get the data set related to. * @return a gradient object or null if not found by legend item */ public final Gradient retrieveFillStyleAsGradient(LegendItem legendItem) { // retrieves data set by legend item Dataset dataset = retrieveDataset(legendItem); // checks if data set is consistent if (dataset != null) { // checks if data set is a point fill stroke style if (dataset instanceof HasPointFillStrokeStyles) { // casts to point fill stroke styles instance HasPointFillStrokeStyles fillStrokeStyles = (HasPointFillStrokeStyles) dataset; // gets key instance Key fillStyleProperty = fillStrokeStyles.getPointFillStyleProperty(); // checks if key is consistent if (Key.isValid(fillStyleProperty)) { // search on cache Gradient gradient = retrieveGradient(dataset, legendItem, fillStyleProperty); // if the value is found // means that the data set has been configured with point fill style if (gradient != null) { // returns the point file style return gradient; } } } // retrieves the object return retrieveGradient(dataset, legendItem, Dataset.CanvasObjectProperty.BACKGROUND_COLOR); } // if here, data set non consistent // then returns null return null; } /** * Returns a gradient object set as border color for a data set related to legend item. * * @param legendItem legend item instance to get the data set related to. * @return a gradient object or null if not found by legend item */ public final Gradient retrieveStrokeStyleAsGradient(LegendItem legendItem) { // retrieves data set by legend item Dataset dataset = retrieveDataset(legendItem); // checks if data set is consistent if (dataset != null) { // checks if data set is a point fill stroke style if (dataset instanceof HasPointFillStrokeStyles) { // casts to point fill stroke styles instance HasPointFillStrokeStyles fillStrokeStyles = (HasPointFillStrokeStyles) dataset; // gets key instance Key strokeStyleProperty = fillStrokeStyles.getPointFillStyleProperty(); // checks if key is consistent if (Key.isValid(strokeStyleProperty)) { // search on cache Gradient gradient = retrieveGradient(dataset, legendItem, strokeStyleProperty); // if the value is found // means that the data set has been configured with point stroke style if (gradient != null) { // returns the point stroke style return gradient; } } } // retrieves the object return retrieveGradient(dataset, legendItem, Dataset.CanvasObjectProperty.BORDER_COLOR); } // if here, data set non consistent // then returns null return null; } /** * Returns a pattern object set as background color for a data set related to legend item. * * @param legendItem legend item instance to get the data set related to. * @return a pattern object or null if not found by legend item */ public final Pattern retrieveFillStyleAsPattern(LegendItem legendItem) { // retrieves data set by legend item Dataset dataset = retrieveDataset(legendItem); // checks if data set is consistent if (dataset != null) { // checks if data set is a point fill stroke style if (dataset instanceof HasPointFillStrokeStyles) { // casts to point fill stroke styles instance HasPointFillStrokeStyles fillStrokeStyles = (HasPointFillStrokeStyles) dataset; // gets key instance Key fillStyleProperty = fillStrokeStyles.getPointFillStyleProperty(); // checks if key is consistent if (Key.isValid(fillStyleProperty)) { // search on cache Pattern pattern = retrievePattern(dataset, legendItem, fillStyleProperty); // if the value is found // means that the data set has been configured with point fill style if (pattern != null) { // returns the point file style return pattern; } } } // retrieves the object return retrievePattern(dataset, legendItem, Dataset.CanvasObjectProperty.BACKGROUND_COLOR); } // if here, data set non consistent // then returns null return null; } /** * Returns a pattern object set as border color for a data set related to legend item. * * @param legendItem legend item instance to get the data set related to. * @return a pattern object or null if not found by legend item */ public final Pattern retrieveStrokeStyleAsPattern(LegendItem legendItem) { // retrieves data set by legend item Dataset dataset = retrieveDataset(legendItem); // checks if data set is consistent if (dataset != null) { // checks if data set is a point fill stroke style if (dataset instanceof HasPointFillStrokeStyles) { // casts to point fill stroke styles instance HasPointFillStrokeStyles fillStrokeStyles = (HasPointFillStrokeStyles) dataset; // gets key instance Key strokeStyleProperty = fillStrokeStyles.getPointFillStyleProperty(); // checks if key is consistent if (Key.isValid(strokeStyleProperty)) { // search on cache Pattern pattern = retrievePattern(dataset, legendItem, strokeStyleProperty); // if the value is found // means that the data set has been configured with point stroke style if (pattern != null) { // returns the point stroke style return pattern; } } } // retrieves the object return retrievePattern(dataset, legendItem, Dataset.CanvasObjectProperty.BORDER_COLOR); } // if here, data set non consistent // then returns null return null; } /** * Returns a data set instance by legend item locator, data set index and index. * * @param legendItem legend item instance to get the data set related to. * @return a data set instance or null if not found by legend item */ public final Dataset retrieveDataset(LegendItem legendItem) { // checks if legend item is consistent if (legendItem != null) { // checks if data set index is the locator // and the index is less than size of data sets if (Undefined.isNot(legendItem.getDatasetIndex()) && currentDatasets.size() > legendItem.getDatasetIndex()) { return getDatasets().get(legendItem.getDatasetIndex()); } else if (Undefined.isNot(legendItem.getIndex()) && !currentDatasets.isEmpty()) { // if here is looking for data index then it uses // the first data set return getDatasets().get(0); } } // if here, legend item is not consistent // or the locator of legend item is not able to locate any dataset return null; } /** * Returns a data set instance by tooltip item locator, data set index and index. * * @param tooltipItem tooltip item instance to get the data set related to. * @return a data set instance or null if not found by tooltip item */ public final Dataset retrieveDataset(TooltipItem tooltipItem) { // checks if tooltip item is consistent // and if data set index is the locator // and the data set index is less than size of data sets if (tooltipItem != null && Undefined.isNot(tooltipItem.getDatasetIndex()) && currentDatasets.size() > tooltipItem.getDatasetIndex()) { return getDatasets().get(tooltipItem.getDatasetIndex()); } // if here, tooltip item is not consistent // or the locator of tooltip item is not able to locate any dataset return null; } /** * Returns a data set instance by scriptable context, data set index and index. * * @param context legend item instance to get the data set related to. * @return a data set instance by scriptable context item or null if not found by scriptable context */ public final Dataset retrieveDataset(DatasetContext context) { // checks if scriptable context is consistent // and if data set index is the locator // and the data set index is less than size of data sets if (context != null && Undefined.isNot(context.getDatasetIndex()) && currentDatasets.size() > context.getDatasetIndex()) { return getDatasets().get(context.getDatasetIndex()); } // if here, tooltip item is not consistent // or the locator of tooltip item is not able to locate any data set return null; } /** * Returns a gradient stored in the data set as color to apply in the chart. * * @param dataset data set instance * @param legendItem legend item instance to get the data set related to. * @param property type of color to search * @return a gradient instance or null if not found by legend item */ private Gradient retrieveGradient(Dataset dataset, LegendItem legendItem, Key property) { // search on callbacks cache Gradient gradient = dataset.getCallbackGradient(property, legendItem.getDatasetIndex(), legendItem.getIndex()); // retrieves the object return retrieveObject(dataset, dataset.getGradientsContainer(), legendItem, property, gradient); } /** * Returns a pattern stored in the data set as color to apply in the chart. * * @param dataset data set instance * @param legendItem legend item instance to get the data set related to. * @param property type of color to search * @return a pattern instance or null if not found by legend item */ private Pattern retrievePattern(Dataset dataset, LegendItem legendItem, Key property) { // search on callback cache Pattern pattern = dataset.getCallbackPattern(property, legendItem.getDatasetIndex(), legendItem.getIndex()); // retrieves the object return retrieveObject(dataset, dataset.getPatternsContainer(), legendItem, property, pattern); } /** * Returns a canvas object stored in the data set as color to apply in the chart. * * @param dataset data set instance * @param container container of canvas object where searching the object * @param legendItem legend item instance to get the data set related to. * @param property type of color to search * @param searchedOnCallback the gradient value got form container of gradients created by a callback * @param type of canvas object to retrieve * @return a canvas object instance or null if not found by legend item */ private T retrieveObject(Dataset dataset, AbstractContainer container, LegendItem legendItem, Key property, T searchedOnCallback) { // checks if the canvas object has been found in the callback cache if (searchedOnCallback != null) { return searchedOnCallback; } // checks if arguments are consistent // and if the container is not empty for the property to search if (Key.isValid(property) && legendItem != null && dataset != null && container != null && container.hasObjects(property)) { // gets all list of canvas object List objects = container.getObjects(property); // the legend item is set by data set index if (Undefined.isNot(legendItem.getDatasetIndex()) && !objects.isEmpty()) { // return the first item return objects.get(0); } else if (Undefined.isNot(legendItem.getIndex()) && objects.size() > legendItem.getIndex()) { // if here is looking for data index return objects.get(legendItem.getIndex()); } } // if here, arguments are not consistent // or the locator of legend item is not able to locate any data set return null; } /** * Returns a string representation for all data sets, in JSON format. * * @return a string representation for all data sets, in JSON format. */ String getDatasetsAsString() { // creates the builder StringBuilder sb = new StringBuilder(); // scans all data sets for (Dataset ds : currentDatasets) { // adds to builder the data in JSON string format sb.append(ds.toFilteredJSON()).append(Constants.LINE_SEPARATOR); } // returns string of builder return sb.toString(); } /* * (non-Javadoc) * * @see org.pepstock.charba.client.ConfigurationElement#load(org.pepstock.charba.client.IsChart, org.pepstock.charba.client.Configuration) */ @Override public void load(IsChart chart, Configuration configuration) { // checks if chart is consistent // configuration will be check in the load data method if (IsChart.isValid(chart)) { // loads data ConfigurationLoader.loadData(configuration, this); // checks if the canvas object handler has been disable if (isCanvasObjectHandling()) { // checks if there is any pattern // scans all data sets for (Dataset dataset : currentDatasets) { // checks if data set has got some patterns // and then activating the plugin if (activateCanvasObjectHandlerPlugin(chart, dataset)) { // if here, // plugin is already added to chart // it shouldn't happen return; } } } } } /** * Checks if data et has got patterns or gradient and then add {@link CanvasObjectHandler} plugin to the chart; * * @param chart chart instance * @param dataset data set to check * @return true if plugin has been added, other wise false */ private boolean activateCanvasObjectHandlerPlugin(IsChart chart, Dataset dataset) { // checks if data set has got some patterns if (!dataset.getPatternsContainer().isEmpty() || !dataset.getGradientsContainer().isEmpty()) { // if here // there are some patterns to load // checks if the plugin to apply pattern is already loaded if (!chart.getPlugins().has(CanvasObjectHandler.ID)) { // adds plugin chart.getPlugins().add(CanvasObjectHandler.get()); // the plugin must be configure // here outside of the plugin container one // because it must be added and configure after // all the others due to the possibility to disable // canvas object handling CanvasObjectHandler.get().onConfigure(chart); } // if here, // plugin is already added to chart // it shouldn't happen return true; } // if here, plugin has not been activated return false; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy